elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  duda sobre punteros en c++
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: duda sobre punteros en c++  (Leído 3,933 veces)
Pedro122h

Desconectado Desconectado

Mensajes: 168


Ver Perfil
duda sobre punteros en c++
« en: 27 Febrero 2022, 04:54 am »

estoy aprendiendo c++ y los punteros son algo confusos para mi y no llego a entenderlos del todo bien:
porque en ciertas ocasiones se pone un * para guardar una variable y en otras no?
Código
  1. //estructura con punteros
  2. #include <iostream>
  3. using namespace std;
  4. void pedirdatos();
  5. void elmayor();
  6. struct empleados{
  7. char nombre[40];
  8. int edad;
  9. float salario;
  10. }empleado[3],*punteroemp=empleado;
  11. int main()
  12. {
  13. pedirdatos();
  14. elmayor();
  15. return 0;
  16. }
  17. //funcion pedir datos del empleado
  18. void pedirdatos(){
  19. cout<<"ingresa los datos del empleados\n";
  20. for(int i=0;i<3;i++){
  21. cout<<"nombre "<<i+1<<": ";cin>>(punteroemp+i)->nombre;
  22. cout<<"salario "<<i+1<<": ";cin>>(punteroemp+i)->salario;
  23. cout<<"edad "<<i+1<<": ";cin>>(punteroemp+i)->edad;
  24. }
  25. }
  26. //funcion para buscar al empleado de mayor edad
  27. void elmayor(){
  28. int mayor=0,pos=0;
  29. for(int i=0;i<3;i++){
  30. if((punteroemp+i)->edad>mayor){
  31. mayor=(punteroemp+i)->edad;
  32. pos=i;
  33. }
  34. }
  35. cout<<"el empleado mayor es:\n";
  36. cout<<"nombre: "<<(punteroemp+pos)->nombre<<endl;
  37. cout<<"salario: "<<(punteroemp+pos)->salario<<endl;
  38. cout<<"edad: "<<(punteroemp+pos)->edad<<endl;
  39. }
  40.  
Por ejemplo en este codigo cuando hago el "cin>>" no es necesario poner el "*"
Pero en este otro codigo si tengo que poner los astericos porque de lo contrario el programa me lanza error
Código
  1. //matriz con punteros
  2. #include <iostream>
  3. #include <stdlib.h>
  4. using namespace std;
  5. int **matriz,filas,columnas;
  6. void pedirdatos();
  7. void mostrardatos();
  8. int main()
  9. {
  10. pedirdatos();
  11. mostrardatos();
  12. for(int i=0;i<filas;i++){
  13. delete[] matriz[i];
  14. }
  15. delete[] matriz;
  16. return 0;
  17. }
  18. //llenardatos de la matriz
  19. void pedirdatos(){
  20. cout<<"cuantas filas va a tener tu matriz: ";
  21. cin>>filas;
  22. cout<<"cuantas columnas va a tener tu matriz: ";
  23. cin>>columnas;
  24. matriz=new int*[filas];
  25. for(int i=0;i<filas;i++){
  26. matriz[i]=new int[columnas];
  27. }
  28. for(int i=0;i<filas;i++){
  29. for(int j=0;j<columnas;j++){
  30. cout<<"matriz["<<i+1<<"]"<<"["<<j+1<<"]: ";
  31. cin>>*(*(matriz+i)+j);
  32. }
  33. }
  34. }
  35. //mostrar datos de la matriz
  36. void mostrardatos(){
  37. cout<<"MATRIZ\n";
  38. for(int i=0;i<filas;i++){
  39. for(int j=0;j<columnas;j++){
  40. cout<<*(*(matriz+i)+j)<<" ";
  41. }
  42. cout<<"\n";
  43. }
  44. }
  45.  
En resumen me gustaria saber para que sirve el operador *
Que diferencia hay entre puntero y *puntero?


« Última modificación: 27 Febrero 2022, 05:18 am por Pedro122h » En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Re: duda sobre punteros en c++
« Respuesta #1 en: 27 Febrero 2022, 05:58 am »



Código
  1. char *variable;
Aqui se declara que variable es un apuntador.

En tu codigo:
Código:
struct empleados{
char nombre[40];
int edad;
float salario;
}empleado[3],*punteroemp=empleado;

Estas declarando una estrucutura con X cantidad de datos y a su vez estas declarando la variable empleado que es un arreglo de longitud 3, Tambien estas declarando la variable punteroemp y lo estas apuntado al primer arreglo que creaste.

Puntero empleado ahora se puede utilizar como un array:

punteroemp[0] seria tendra el mismo valor que empleado[0]
punteroemp[1] seria tendra el mismo valor que empleado[1] etc...

Ahora:

Código:
cin>>(punteroemp+i)->nombre

seria lo mismo que hacer punteroemp.nombre existen varias maneras de jugar con los apuntadores.

El * solo se utiliza para declar a la variable como apuntador.

Saludos!








En línea

Pedro122h

Desconectado Desconectado

Mensajes: 168


Ver Perfil
Re: duda sobre punteros en c++
« Respuesta #2 en: 27 Febrero 2022, 17:30 pm »

Gracias por su respuesta pero creo que no me hice entender muy bien
Asi que voy a ser mas directo
En esta linea de codigo se muestra el valor al que apunta el puntero
Código
  1. //codigo1
  2. cout<<"edad: "<<(punteroemp+pos)->edad<<endl;
  3.  
//Codigo2
Mientras en esta otra tengo que poner los astericos por que de lo contrario solo me va a mostrar la direccion de memoria y no el valor
Código
  1. //codigo2
  2. cout<<*(*(matriz+i)+j)<<" ";
  3.  
Porque en el primer caso no es necesario poner los astericos mientras en el segundo si hay que ponerlo?
En línea

K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: duda sobre punteros en c++
« Respuesta #3 en: 1 Marzo 2022, 21:27 pm »

Gracias por su respuesta pero creo que no me hice entender muy bien
Asi que voy a ser mas directo
En esta linea de codigo se muestra el valor al que apunta el puntero
Código
  1. //codigo1
  2. cout<<"edad: "<<(punteroemp+pos)->edad<<endl;
  3.  
//Codigo2
Mientras en esta otra tengo que poner los astericos por que de lo contrario solo me va a mostrar la direccion de memoria y no el valor
Código
  1. //codigo2
  2. cout<<*(*(matriz+i)+j)<<" ";
  3.  
Porque en el primer caso no es necesario poner los astericos mientras en el segundo si hay que ponerlo?
Esto es porque en el primer caso no estás mostrando el contenido de un puntero sino de una variable "normal" (edad) aunque estés accediendo a esa variable por medio de un puntero.
Si ves en tu código original, (línea 8) 'edad' es una variable de tipo int.

Supongamos que en lugar de tu código original, tienes el siguiente:
Código
  1. struct Empleado {
  2.  int* edad;
  3. };
  4.  
  5. int main() {
  6.  Empleado *puntero_empleado = new Empleado; // Reservamos memoria para el puntero a 'Empleado' -> No relevante ahora mismo
  7.  
  8.  // 'puntero_empleado->edad' es equivalente a: '(*puntero_empleado).edad'
  9.  // La primera sintaxis es mas elegante y mas facil de leer pero significa exactamente lo mismo
  10.  puntero_empleado->edad = new int; // Reservamos memoria para poder guardar un int (ahora es necesario porque edad es un puntero) -> No relevante ahora mismo
  11.  puntero_empleado->edad = 5; // ERROR!! Estas asignando un int (5) a un puntero
  12.  *(puntero_empleado->edad) = 5; // CORRECTO!!
  13.  *(*(puntero_empleado).edad) = 5; // Esto tambien es correcto pero se lee peor
  14.  
  15.  cout << puntero_empleado->edad << endl; // Esto te mostrara la direccion de memoria del puntero 'edad'
  16.  cout << *(puntero_empleado->edad) << endl; // Esto te mostrara el contenido de la direccion de memoria del puntero 'edad': 5
  17.  
  18.  // Si reservamos memoria dinamica mediante 'new', al dejar de usarla hay que liberarla con 'delete' -> No relevante ahora mismo
  19.  delete(puntero_empleado->edad);
  20.  delete(puntero_empleado);
  21. }
Como ves, si la variable 'edad' que es la que tú realmente estás usando fuera un puntero, también tendrías que usar el asterisco

En cambio, en el segundo caso que muestras, estás accediendo a una variable que es un puntero (más concretamente una matriz = puntero a punteros) y por eso tienes que usar el asterisco.

Entendiendo bien los operadores (* y &) puedes concatenar tantos punteros/no punteros como quieras. Claro que si concatenas demasiado perderás el hilo de a qué estás accediendo:
  • Operador * -> Sólo se puede usar con punteros: Devuelve el contenido que está almacenado en la dirección de memoria a la que apunta el puntero.
  • Operador & -> Se puede usar con cualquier tipo de variable: Devuelve la dirección de memoria de esa variable.

    Código
    1. int var = 5; // Variable "normal"
    2.  
    3. // NOTA: Cuando se asigna un valor (direccion de memoria) a un puntero al mismo tiempo que se declara estamos ante una situacion especial
    4. // Aunque estemos usando el asterisco realmente no estamos accediendo al contenido al que apunta, en este momento el asterisco solo significa que hemos declarado un puntero
    5. int *p_var = &var; // Puntero a int
    6. // La linea anterior es equivalente a:
    7. // int *p_var;
    8. // p_var = &var;
    9.  
    10. cout << var << endl; // Muestra el contenido de var: 5
    11. cout << &var << endl; // Muestra la direccion de memoria donde se esta guardando 'var'. Imaginemos que es: 0x1 (realmente sera un numero mas largo)
    12.  
    13. // Ahora estamos accediendo al contenido del puntero p_var -> ¿Que guarda un puntero? Una direccion de memoria, en este caso la de 'var'
    14. cout << p_var << endl; // Muestra: 0x1
    15. cout << *p_var << endl; // Muestra el contenido guardado en la direccion de memoria guardada en 'p_var' -> p_var = 0x1 -> Contenido en 0x1: 5
    16. cout << &p_var << endl; // Muestra la direccion de memoria donde se esta almacenando el puntero 'p_var'. Supongamos 0x5 (realmente sera otro numero largo)
    17.  
    18. // Ahora complicamos mas la situacion:
    19. int **pp_var; // Doble puntero -> Significa que tiene que guardar una direccion de memoria pero no una cualquiera. Tiene que guardar la direccion de memoria de un puntero
    20. pp_var = &p_var; // Aqui tenemos la direccion de memoria de un puntero (0x5), nos sirve.
    21.  
    22. // Y ahora llega lo divertido. Te reto a entender que se esta mostrando en cada momento y si lo consigues, ya tendras los punteros mucho mas dominados de lo que pensabas:
    23. cout << pp_var << endl;
    24. cout << &pp_var << endl;
    25. cout << *pp_var << endl;
    26. cout << **pp_var << endl;
    27.  

    Puedes hacer un programa con el código anterior y ejecutarlo para verlo con valores de verdad.
    Verás que aunque las direcciones de memoria son más largas, se cumple que el valor real de lo que yo he llamado 0x1 en la línea 11 es el mismo que en la línea 14. Y así con 0x5 también.

    PD: Soluciones:
    Código
    1. cout << pp_var << endl; // Muestras lo que esta guardando el puntero doble 'pp_var' -> Guarda la direccion de memoria de 'p_var' -> 0x5
    2. cout << &pp_var << endl; // Muestra la direccion de memoria propia de 'pp_var' -> Sera otra diferente: 0x15 por ejemplo
    3. cout << *pp_var << endl; // Muestra el contenido de 'p_var' -> 'p_var' contiene la direccion de memoria de 'var' -> 0x1
    4. cout << **pp_var << endl; // Muestra el contenido del contenido de 'p_var' -> 'p_var' contiene la direccion de memoria de 'var' (0x1) -> Esta direccion contiene el valor de 'var' -> 5
En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
Pedro122h

Desconectado Desconectado

Mensajes: 168


Ver Perfil
Re: duda sobre punteros en c++
« Respuesta #4 en: 3 Marzo 2022, 05:05 am »

Muchas gracias me haz aclarado muchas dudas al final no era tan complicado como parece  :silbar: ;-)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
duda sobre punteros
Ejercicios
maryrisas 1 4,120 Último mensaje 23 Febrero 2006, 17:59 pm
por [[JONAS]]
[duda] sobre punteros y signed
Programación C/C++
AlxSpy 6 3,570 Último mensaje 9 Enero 2011, 20:13 pm
por AlxSpy
Duda sobre punteros
Programación C/C++
adissenys 3 2,379 Último mensaje 17 Noviembre 2012, 22:59 pm
por Ferno
Duda sobre punteros en C
Programación C/C++
mester 4 3,134 Último mensaje 29 Julio 2015, 22:46 pm
por mester
ayuda con una duda sobre punteros
Programación C/C++
DobleGa 1 1,742 Último mensaje 7 Mayo 2017, 17:18 pm
por CalgaryCorpus
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines