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

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  consulta sobre el uso del ampersand en variables de tipo string
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: consulta sobre el uso del ampersand en variables de tipo string  (Leído 4,251 veces)
etcheverrypablol

Desconectado Desconectado

Mensajes: 37


¡Hoy mejor que ayer, mañana mejor que hoy!


Ver Perfil
consulta sobre el uso del ampersand en variables de tipo string
« en: 18 Enero 2016, 19:38 pm »

Hola, aparezco por aquí con otra duda. Este programa:

#include <stdio.h>

int main(int argc, char const *argv[])
{
   char pax[]="Juan Sin Miedo";
   printf("%s %s\n",pax,&pax[4]);
   puts(pax);
   puts(&pax[4]);
   return 0;
}

lo que hace es mostar por pantalla lo siguiente:

Juan Sin Miedo  Sin Miedo
Juan Sin Miedo
 Sin Miedo

No entiendo, qué es lo que hace la sentencia puts(&pax[4]);.
Por lo que veo comienza a mostrar la cadena desde la posición 4. Pero no sé por qué se hace uso del ampersand ni cómo es que funciona este operador en este caso.

Alguno de ustedes me puede explicar por favor. Muchas gracias.


En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: consulta sobre el uso del ampersand en variables de tipo string
« Respuesta #1 en: 18 Enero 2016, 19:46 pm »

& devuelve la dirección de memoria de la variable que le sigue.
%s de printf y puts esperan la dirección de memoria del inicio de una cadena. Un puntero es una dirección de memoria y el nombre de un array también actúa como un puntero.
En cambio cuándo haces pax[4] estás accediendo a una variable de tipo char, no a una dirección. Así para que la opción %s de scanf y puts escriban la cadena a partir de pax[4] hasta el final debes pasárselo como dirección de memoria y eso se hace con el & delante.

Cuando llegues a los punteros sabrás más de ello.


En línea

etcheverrypablol

Desconectado Desconectado

Mensajes: 37


¡Hoy mejor que ayer, mañana mejor que hoy!


Ver Perfil
Re: consulta sobre el uso del ampersand en variables de tipo string
« Respuesta #2 en: 18 Enero 2016, 20:12 pm »

Muchas gracias por responder MAFUS! Estoy muy agradecido :)
Ahora lo entiendo. He visto ya sobre punteros en pascal, y un poco en c, y no me daba cuenta.
Ahora una duda, vos dijiste que %s de printf y puts esperan la dirección de memoria del inicio de una cadena. Eso, no es siempre así, ¿o si?. Porque cuando le pasas una cadena solamente, como el caso de pax, no le pasas la dirección.
En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: consulta sobre el uso del ampersand en variables de tipo string
« Respuesta #3 en: 18 Enero 2016, 20:28 pm »

Sí, pax, en este caso, es un array y por tanto cuándo se acceder a la variable solo con su nombre estás accediendo a la dirección el primer elemento de este array.
Como prueba de ello puedes probar lo siguiente:
Código
  1. /* Después de char pax[]="Juan Sin Miedo"; */
  2. char *puntero_a_char = pax;
  3. printf("%s %s\n",puntero_a_char, &puntero_a_char[4]);
  4. puts(puntero_a_char);
  5. puts(&puntero_a_char[4]);
En línea

Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: consulta sobre el uso del ampersand en variables de tipo string
« Respuesta #4 en: 19 Enero 2016, 14:25 pm »

Porque cuando le pasas una cadena solamente, como el caso de pax, no le pasas la dirección.

Recuerda que en C las cadenas son arreglos de datos char, y como en todo arreglo en C, el nombre del arreglo es un apuntador al primer elemento del mismo. En otras palabras, el nombre de la cadena es realmente una variable tipo char* (puntero a char) que contiene la dirección de memoria del primer carácter de la misma.

Código
  1. char str[] = "Hola mundo";
  2.  
  3. printf( "contenido de str: %s\n", str );
  4. printf( "pero str es un puntero cuyo valor es: %p\n", str );
  5. printf( "y apunta al primer elemento el cual es --> '%c'\n", *str );

Salida:

    contenido de str: Hola mundo
    pero str es un puntero cuyo valor es: 0xbfcbe9b5
    y apunta al primer elemento el cual es --> 'H'


Saludos, Yoel.

En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
D4RIO


Desconectado Desconectado

Mensajes: 1.004


U N I X


Ver Perfil WWW
Re: consulta sobre el uso del ampersand en variables de tipo string
« Respuesta #5 en: 19 Enero 2016, 14:59 pm »

Excelente respuesta la de Yoel, muy completa.

Agrego algo más técnico, por si interesa:

Si descendemos al nivel de la implementación, las llamadas a funciones de C meten los parámetros en la pila (push). La función sabe cuánto debe sacar de la pila para ser usado como parámetro (exceptuamos acá las funciones variádicas), esto porque le dijimos al compilador de C el tipo de cada parámetro y, con ello, su tamaño.

Imagina ahora que le pasamos str, que es un char[]. Si pasáramos toda la cadena por 'valor' a la función, cada cadena podría meter una cantidad de carácteres diferente a la pila, para lo cual la función debería sacar carácter por carácter de la pila, verificar que no sea un '\0' y seguir. No es que sea imposible, pero es algo sucio y que no sigue la línea de comportamiento de las llamadas donde se pasa un vector cualquiera, digamos, de enteros, que se pasan por referencia. La función ciertamente NO tiene idea de cómo saber dónde terminar de procesar un vector de enteros (se podría, pasando el tamaño, pero eso ensucia más la convención, y queremos mantener las cosas simples).

Por eso dentro de la convención de llamadas a función de C se eligió la forma más sencilla y comprensible posible: Cualquier cosa que sea un vector (blabla[]) se pasa por referencia a las funciones, esto es, se pasa un puntero. De esa forma las funciones saben que deben sacar de la pila un puntero, que es siempre del mismo tamaño, tamaño dirección de memoria del sistema.

En las funciones variádicas nosotros podemos sacar parámetros de la pila como nos de la gana, y eso nos permitiría pasar un string por valor. Sin embargo, cuando pases un char[], notarás que NO se mete la cadena en la pila del sistema, aunque uses varargs la cadena simplemente no está ahí, y esto es porque cuando el compilador de C lee que pasa un char[], mete el puntero a la pila. Está programado para hacer eso.

Saludos, espero haber agregado conocimiento y no dudas.
En línea

OpenBSDFreeBSD
etcheverrypablol

Desconectado Desconectado

Mensajes: 37


¡Hoy mejor que ayer, mañana mejor que hoy!


Ver Perfil
Re: consulta sobre el uso del ampersand en variables de tipo string
« Respuesta #6 en: 20 Enero 2016, 14:15 pm »

Hola Yoel, tenía conocimiento de eso. Lo que no sabía es que exitía el código de formato %p que te permite mostrar la dirección de memoria de un puntero. La verdad chicos que me sirven muchisimo sus respuestas. Gracias! :)



Hola D4RIO, te aseguro que si tengo más dudas jajaja. Es muy interesante la explicación que diste. Me gusta saber cosas de ese nivel. Aun me falta mucho por aprender y hay algunas cosas que no entendí de las que dijiste. Pero muy pronto lo haré. Gracias por su tiempo y dedicación chicos.
« Última modificación: 20 Enero 2016, 14:58 pm por Eternal Idol » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines