Curso completo de programación con lenguaje C

GeGe

#719 Exacto , eso era lo que buscaba jaja, me exprese mal seguramente. Entiendo tendria que poner en cargar algo parecido a lo que puse en buscar con el flag que cada vez que me pregunte que numero quiero que verifique , para que cuando ponga el numero 2 ahi me deje de pedir numeros

Muchas gracias! , entendi el concepto no es que salta de el cargar a buscar y despues vuelve a cargar , sino que primero carga todo por eso nunca entra en buscar y luego busca. Ya se donde cometo el error. en serio muchas gracias a todos los que respondieron :D

#720 Te doy la razon jaja. La proxima si tengo alguna duda pongo el codigo y el problema :D

2
1 año después
d8D

Upeo esta obra de arte 👌

3
1 mes después
EruGreen

Hola, estoy aprendiendo a programar en C y tengo una duda.

No entiendo cual es la funcion de declarar las variables dentro de una estructura como punteros, por ejemplo:

struct persona{
   char *nombre;
   int telefono;
}

Cual seria la diferencia de hacerlo asi?

struct persona{
   char nombre;
   int telefono;
}

siento si es algun muy tonto, pero no lo encuentro explicado por ninguna parte. Gracias de antemano.

2 respuestas
CiudadanoEj

#723 punteros tiene su que y es algo complicado de entender al principio, basicamente usando punteros lo que estas haciendo es apuntar a una direccion de memoria donde se encuentra la variable o que quieres guardar (mas adelante seguramente veas que puedes reservar este espacio de memoria y crear dinamicamente los objetos segun lo que necesites en ese momento)

1 respuesta
EruGreen

#724 pero he visto que despues por ejemplo hacen:

persona1.nombre="david";
persona1.telefono=666666666;

sabes? como que no recibe un trato especial por estar declarado como puntero, es lo que me cuesta entender? si no llego a este nivel de comprension, deberia trabajar de forma indistinta si es un puntero o no?

1 respuesta
CiudadanoEj

#725 porque una vez declarado ya lo tratas como una variable normal no has de estar poniendo constantemente el * delante del nombre

1 respuesta
EruGreen

#726 pero no deberia de haber un trozo de codigo que diga:

char nombre_persona;
nombre=&nombre_persona;

es confuso el tema la verdad, es sobretodo aqui donde esta mi duda.

3 respuestas
CiudadanoEj

#727 nose si he entendido bien tu pregunta pero eso solo deberias hacerlo si el nombre es un puntero algo asi:
char *nombre = NULL;
char nombre_persona ;
nombre = &nombre_persona;

y por ejemplo para cambiar el valor podrias hacerlo asi:
*nombre = 'EruGreen'

1 respuesta
EruGreen

#728 si, eso lo entiendo, lo que no comprendo es de que te sirve tener *nombre si no haces eso... *nombre tiene dentro solo un codigo hexadecimal que corresponde a un espacio de memoria no? es lo que no entiendo.

1 respuesta
Hordeo

#723 Un puntero es una variable que almacena una posición en memoria. Esto nos permite, entre otras cosas, poder modificar el valor de nuestra variable local en diferentes métodos externos (Ej funciones). Al saber en que posición de nuestra memoria se encuentra, podemos ir a dicha posición y modificar su contenido.

Te pongo un ejemplo en java, pero es lo mismo: https://app.codingrooms.com/w/rH5np7p4eBwh

A un puntero se le puede introducir datos como lo harías a una variable normal o mediante su dirección en memoria, no tiene nada de extraño. Eso sí, los punteros te ofrecen mayor flexibilidad pero tienes que eliminarlos de memoria ya que C no lo hace por sí solo. No se si era marcando su valor como null o algo asi

cabron

#727

Me voy a limitar a responder a la duda concreta que has puesto, es decir al tema de una cadena, creo que va a ser más fácil que si generalizo la respuesta, lo que quiero decir es que los punteros no se limitan a cadenas, pero yo me voy a centrar en eso para no liarte más.

char nombre; es una variable de tipo char. Solo puede contener un caracter, no puedes hacer

char cadena = "hola que tal";

Solo puedes hacer

char cadena = "h";

Si quieres meter más de un caracter necesitas un array:

char cadena[] = "hola que tal";

Y aquí entra una de las características de C que al principio son muy confusas, y es que los punteros y los arrays son lo mismo, pero el puntero tiene una ventaja, y es que si usas un array tienes que saber de antemano la longitud de la cadena por que cuando declaras un array tienes que decir el tamaño del array, sin embargo si usas un puntero no necesitas saber la longitud, tú mismo has puesto antes como funciona:

#729EruGreen:

*nombre tiene dentro solo un codigo hexadecimal que corresponde a un espacio de memoria

y ese espacio de memoria puede tener la longitud que tu quieras, por eso con un puntero dices "yo apunto aquí y ya me dirán que longitud tiene", mientras que si usas un array tienes que poner desde el principio la longitud.

2
Hordeo

#727 No tiene porque. Por pasos:

Cuando haces: "char *nombre" estas reservando un espacio en memoria y copiando su dirección en la variable "nombre". Este es un tipo de dato char de valor null.

Cuando haces: "nombre=&nombre_persona" estas copiando la dirección de memoria de "nombre_persona" en la variable "nombre". El contenido del puntero es el mismo que la variable "nombre_persona". Y si esta modifica su valor el puntero mostrará los datos actualizados de dicha variable porque lo único que haces es decirle que copie su dirección de memoria.

Al principio es un lio pero te acostumbrarás.

1 respuesta
cabron

#732

#732Hordeo:

Cuando haces: "char *nombre" estas reservando un espacio en memoria y copiando su dirección en la variable "nombre". Este es un tipo de dato char de valor null.

No, eso es incorrecto.

Cuando haces char *nombre; no reservas nada (bueno sí el puntero que también ocupa memoria pero para no confundir vamos a igornarlo), y el valor no es null, el valor es sin definir. En C no hay nada que se inicialice a null, lo estás mezclando con java.

Realmente no deberías usar java como ejemplo como has hecho en un post anterior, por que java no tiene punteros, tiene referencias que es parecido pero no es lo mismo.

1 respuesta
Hordeo

#733 Ya sé que Java no tiene punteros como tal, como bien has dicho usa referencias, pero en esencia se utilizan para prácticamente lo mismo. Te permiten modificar una variable local en diferentes métodos externos (Ej funciones). Por ejemplo modificar el valor de una variable local en una función de tipo void (que no tiene return), modificar un vector de tipo int... etc. Ahí si o sí tienes que trabajar con punteros porque no puedes devolver con un return un tipo de dato array/vector (vamos o al menos eso recuerdo, a ver si me falla la memoria XD)

Siento si no utilizo la terminología adecuada, hace ya un tiempo que lo ví. Con respecto a los punteros tipo null, es cierto, sin embargo lo que yo quería explicarle es que puede declarar un puntero sin tener que apuntar a ninguna posición de memoria. Que por defecto al inicializar un puntero reservas un espacio en memoria y este obtiene unos valores sin definir. No podemos ignorar esto o va a pensar que siempre que crea un puntero tiene que asignarle algun valor o le dará error de algun tipo.

La idea es que entienda para qué se usan los punteros y como puede hacer lo siguiente: 1) inicializarlos 2) asignarle valores 3) saber cuando se deberían usar 4) comprender las diferencias entre una variable primitiva y un puntero.

Utilizo java porque es lo que tengo más a mano, de todas formas puede mirarse ejemplos en internet de como funcionan los punteros si no le ha quedado muy claro. Pero la mejor forma de aprender es programar ejemplos sencillos y hacer mucho uso del "println" para que comprenda que es lo que pasa con ese puntero a lo largo del recorrido de un programa.

1 respuesta
cabron

#734

te lo decía solo por que he visto a gente tener mucha confusión cuando se pasa de c a java o al revés por pequeños detalles como ese, al principio puede ser útil compararlo con algo conocido pero luego ocurre algún problema que requiere entender exactamente como funciona cada cosa y la gente se lía.

1 respuesta
Hordeo

#735 Yo mismo di el salto de C++ a Java y es cierto, al principio te lías un poco, pero la idea es comprender como funciona de forma general y luego ver como se aplica en ese lenguaje. Hay lenguajes que directamente no tienen punteros, pero si uno de ellos lo tiene, al menos deberías comprender para qué se usan en otros lenguajes de programación. Ir con esa idea en la cabeza y luego ya te pondrás a ver como se declara y que diferencias tiene con respecto al lenguaje al que estás acostumbrado. Anda que no me habré pasado tardes buscando el equivalente a X en el lenguaje Y.

Un ejemplo es el uso de las variables, en cada lenguaje se definen de una forma, pero todas ellas se utilizan para lo mismo. Almacenar datos. Con el tema de la herencia más de lo mismo, se declara distinto en cada lenguaje, pero todas ellas respetan la jerarquía de herencia pública, protected o private. Si sabes como funciona de manera general, solo tienes que aprenderte esos pequeños matices que lo diferencian con otros lenguajes.

Saludos compañero

EruGreen

Estoy haciendo una prueba, y no entiendo bien que hago mal...

typedef struct {
int *data_ptr;
}data_t;

void restador (data_t *data){
while (data -> data_ptr>0){
printf ("Resta: %ls \n", data -> data_ptr);
data -> data_ptr = (data -> data_ptr-1);
}
}

void main(){

int random_num;

data_t *programa;

srand(time (NULL));
random_num=(rand()%100)+1;
programa->data_ptr=random_num;

   restador (&programa);

}

Esto me da los siguientes warnings:

1.c: In function ‘main’:
1.c:72:20: warning: assignment to ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
72 | programa->data_ptr=random_num;
| ^
1.c:92:12: warning: passing argument 1 of ‘restador’ from incompatible pointer type [-Wincompatible-pointer-types]
92 | restador (&programa);
| ~~~
| |
| data_t ** {aka struct <anonymous> **}
1.c:50:31: note: expected ‘data_t *’ {aka ‘struct <anonymous> *’} but argument is of type ‘data_t **’ {aka ‘struct <anonymous> **’}
50 | void restador (data_t *data){

En que estoy fallando? es desesperante esto de los punteros y las estructuras...

2 respuestas
cabron

#737

Pues así por encima, los dos fallos más gordos que veo son:

data_t *programa;

Eso es un puntero. Los punteros nada más crearlos no apuntan a nada válido. Tienes que reservar un bloque de memoria y hacer que el puntero apunte a ese bloque.

programa->data_ptr=random_num;

data_ptr es un puntero, random_num una variable. No puedes asignar el valor de una variable a un puntero, los punteros contienen direcciones de memoria, tendrías que usar:

programa->data_ptr=&random_num

De todas formas creo que deberías tener claro que la utilidad de los punteros viene cuando no sabes cuanto espacio vas a usar para algo, por que sinceramente ese ejemplo no tiene sentido.

Si sabes que una cadana tiene 10 caracteres pues declaras esto:

char miCadena[10];

si no sabes cuantos caracteres va a tener haces esto:

char *miCadena;

y durante de la ejecución del programa, cuando sepas cuanto necesitas, reservas la memoria del tamaño adecuado y haces que el puntero apunte a esa región de memoria

Hordeo

#737 Te lo he puesto en uno de mis mensajes amigo, usa el print porque para empezar ese bucle no esta trabajando con numeros sino con DIRECCIONES DE MEMORIA. Le estas diciendo, si 0x7ffdc30da200 es mayor que 0... y el bucle nunca para!! En un rato te intengo corregir el codigo con comentarios a ver si asi logras entenderlo.

Tras corregirlo creo que aún no entiendes muy bien el uso de los punteros. No sabes para que se usa el asterisco o que tipo de datos le tienes que pasar a la función. De nuevo, no quiero sonar pesado, pero si ejecutas tu programa y no funciona bien debes hacer una labor de debug para saber que esta ocurriendo. Yo usaría mejor un cout y si quieres luego lo pones bonito usando un printf, solo te digo que si usas un printf deberías leer muy bien los términos que se usan con el % porque no le estabas pasando el tipo de dato correcto.

Repaso rápido:

int numero = 10;
int *puntero = &numero;
cout << puntero << "\n"; ==> IMPRIME DIRECCIÓN DE MEMORIA
cout << *puntero << "\n"; ==> IMPRIME VALOR DE LA VARIABLE EN DICHA DIRECCIÓN DE MEMORIA

PD: Codigo en un compilador online https://onlinegdb.com/orlzKFeV_

B

Ahora entiendo cuando dicen lo de que x lenguaje deriva de C