Curso completo de programación con lenguaje C

He3maN0

Pero eso no lo hace solo? Osea yo en este caso,al pedirme el numero si presiono enter simplemente pasa de linea

herre

#419

Cuando declaras una variable mediante

int a;

el compilador reserva espacio en memoria para almacenar el entero representado por a, pero no le asigna ningún valor, puede haber cualquier cosa ahí dentro. Si utilizas a sin inicializarla (osea, darle algún valor inicial adecuado) y tu programa necesita que su valor cumpla alguna condición, puede liarse parda.

diees una función que nos creamos para terminar el programa (exit(1) termina la ejecución del programa devolviendo 1, lo que indicaría un error) de forma cómoda, mostrando un mensaje.

EOF es lo que te ha dicho #420. Es uno de los posibles valores que puede devolver scanf. Lo almacenamos en rc y nos aseguramos que si rc == EOF, el programa termina, ya que no tiene un valor correcto para continuar.

herre

Por cierto, EOF no es ningún valor mágico, es simplemente el int -1. Es una macro definida en stdio.h:

#define EOF (-1)

Creo que aun no se han dado macros aqui, pero #define EOF (-1) le indica al "compilador" (realmente, al preprocesador) que antes de nada, sustituya todas las apariciones de EOF en el código por -1.

EDIT: Esto se está llendo de madre xD, pero quiero aclarar una cosa. EOF es el concepto fin de archivo. A nivel sistema operativo, este está indicado por un valor especial que se guarda en el disco duro al final de cada archivo, obviamente. El EOF de C es una macro que tiene el valor -1, y scanf tiene la convención de devolver -1 cuando lee el indicador EOF de un archivo. Pero la macro EOF de C no es el valor EOF de tu sistema operativo.

Saiko9

Me puede echar alguien un cable con esta barrera de sincronización de hilos que estoy haciendo? postee paginas antes sobre una duda de este tema y ya comprendo mas o menos como funciona pero no me sale xDD

Es una barrera que usa un mutex y variable condicional, su funcionamiento es:
Si hay 4 hilos por ejemplo tienen que quedarse todos esperando hasta que llegue el último, entonces quedan sincronizados y el programa puede avanzar. Por eso eso lo que hago es si no eres el ultimo hilo (el contador no es igual al numero de hilos) quedate esperando en la variable cond. y si eres el ultimo despierta a todos y sigue.

El problema obviamente es el de siempre en la programación concurrente xD se me queda bloqueado el programa, y como no entiendo todavia mucho esta forma de programar no se si estoy haciendo alguna gilipollez en el wait.

La estructura de datos es esta:

typedef struct
{
    pthread_mutex_t mutex;  /* Cerrojo de la barrera */
    pthread_cond_t cond;    /* Variable condicional donde se bloquean los hilos */
    int nr_threads_arrived; /* Numero de hilos que han llegado a la barrera */
    int max_threads;        /* Numero de hilos que han de sincronizarse en la barrera */
}sys_barrier_t;

Codigo de la barrerA:

#include "barrier.h"
#include <errno.h>


#ifdef POSIX_BARRIER

/* Wrapper functions to use pthread barriers */

int sys_barrier_init(sys_barrier_t* barrier, unsigned int nthreads) {

return pthread_barrier_init(barrier,NULL,nthreads);
}

int sys_barrier_destroy(sys_barrier_t* barrier) {
    return pthread_barrier_destroy(barrier);
}

int sys_barrier_wait(sys_barrier_t *barrier) {
    return pthread_barrier_wait(barrier);
}

#else


/* Inicializacion de la barrera */
int sys_barrier_init(sys_barrier_t *barrier, unsigned int nr_threads)
{


barrier->nr_threads_arrived=0; //inicializamos la variable a 0
barrier->max_threads = nr_threads; //maximo de hilos de la barrera
pthread_mutex_init(&barrier->mutex, NULL); //iniciar una variable de tipo mutex dentro de nuestra estructura en la barrera
pthread_cond_init(&barrier->cond, NULL); //iniciar la variable condicional


return 0;
}

/* Destruccion de los recursos de la barrera */
int sys_barrier_destroy(sys_barrier_t *barrier)
{
	




   pthread_mutex_destroy(&barrier->mutex); //destruimos mutex
   pthread_cond_destroy(&barrier->cond); //destruimos variable condicional

   return 0;
}

/* Operacion de sincronizacion/espera en la barrera */
int sys_barrier_wait(sys_barrier_t *barrier)
{
    pthread_mutex_lock(&barrier->mutex); //el hilo que llega a la barrera adquiere el  mutex

barrier->nr_threads_arrived++; //incrementa de forma atomica el contador nr_threads_arrived


while (barrier->nr_threads_arrived != barrier->max_threads) {  //Si aun faltan mas hilos por llegar el hilo se bloquea con la V.cond
			pthread_cond_wait(&barrier->cond, &barrier->mutex);        //hilo bloqueado en la varialbe cond a la espera de que llegue el último
		}

if (barrier->nr_threads_arrived == barrier->max_threads){ //Si es el ultimo hilo en llegar...
	    barrier->nr_threads_arrived=0;  //1 resetea el estado de la barrera para la siguiente sys_barrier_wait()
		pthread_cond_broadcast(&barrier->cond); //2 despierta a todos los hilso bloqueados en la V.cond

	}



pthread_mutex_unlock(&barrier->mutex);// Liberar mutex antes de salir de la funcion
return 0;
}

#endif /* POSIX_BARRIER */

Gracias.

pd: joder se me ha descolcado un poco con los comments aunque es bastante poco codigo y lo importantes es el wait, luego si puedo lo pongo mejor sorry.

He3maN0

Me puede ayudar alguien con el ejercicio 7(el de hacer el factorial) llevo 1 dia entero trabado y intentadolo,lo unico que consigo es hacer 12+23+34+45.Pero eso obviamente no sirve.He visto un ejercicio resuelto pero le pasa lo mismo que a mi y de todas formas no quiero realmente que me digais como hacerlo,si no que me hagais comprenderlo xd no se si me explico

2 respuestas
Saiko9

#425

Pues lo primero que te digo es que si el ejercicicio es de factorial te sobran las sumas ya que por ej factorial(3) = 123 = 6, asi que no se si pides eso pero bueno xD te digo el del factorial ya que es facil y si es otro pues supongo que se resolverá casi igual.

Una definicion rapida y no correcta del todo de factorial seria que es la multiplicacion del numero(n) que quieras por n-1 hasta que llegues a 1 por lo tanto:

n E naturales ( si quieres meter el factorial de 0 tendrias que decir que sea 1 directamente)

por lo tanto planteariamos la función así:
f(n) =
1 si n=0
n * f(n-1) si n > 1;

Pseudocodigo rapido:

factorial (int n)
si (n == 0 ) return 1;
si no n= n * factorial(n-1);

suponiendo n >=0;

escribirlo en codigo es bastante facil.

Edito poniendolo bien del todo que lo que he puesto no esta mal pero es un poco gilipollez hacerlo hasta 1 xD.

gonya707

#425 una pista desde el lado matematico seria esta:

n! = n * (n-1)!

vamos que si quieres sacar el factorial de 5:

5! = 5 * 4!

y a su vez

4! = 4 * 3!
3! = 3 * 2!

recursividad!

Saiko9

Conseguí solucionar el problema de #424 por si a alguien le pasa algo parecido, la solución era en el while despues de que los hilos se queden esperando en la var.cond hacer un unlock del mutex y un return de la función para que salgan.

1
14 días después
FoxWinterMan

Hola chicos tengo un enunciado que no logro entender, a ver si alguno de vosotros me puede iluminar que pide:

La serie Alcalaina esta formada por los siguientes numeros:
1,2,3,8,19,86,455....
donde se observa que, a excepción de los 3 primeros términos, el elemento de orden n se calcula como la suma del elemento n-1 más el cuadrado del elemento n-2 mas el elemento n-3.
Programar una función recursiva en C que proporcione el término de orden n de la serie.

Entiendo como hacer la función desde el 1,2,3 y demás, pero no entiendo el enunciado.
¿Que pide? Que meta un numero y averigue su serie? que empieze desde el 1,2,3 y averigue si algun numero forma esta serie?

2 respuestas
cabron

#429

"Programar una función recursiva en C que proporcione el término de orden n de la serie."

Yo lo que entiendo es que tienes que hacer un programa al que le pidas el número 50 de la serie y te lo de, o el número 100 de la serie, o el que sea. Por ejemplo si le pides el 4º t tiene que dar 8, si lo pides el 6º devolverá 86, etc.

gonya707

#429 es como te dicen arriba, tienes que hacer la funcion

int alcalaina(int n);

En la que por ejemplo esto

printf("%d\n", alcalaina(2));
printf("%d\n", alcalaina(3));
printf("%d\n", alcalaina(4));

te devuelva esto:

2
3
8
1 respuesta
FoxWinterMan

#431 La solucion a la que he llegado ha sido esta:

Cutre o eso creo, pero funciona :)

1 respuesta
Camp1

#432 por legibilidad te aconsejo que antes del main solo declares las funciones/procedimientos y ya después del main las implementes.

1
shortyStyle

#385 Solo por curiosidad, qué IDE estás usando?

1 respuesta
gonya707

#434 eso es el sublime text

2
Overburden

Alguien sabría poner un buen ejemplo de la diferencia de paso de parámetros por valor y paso de parámetros por referencia?? muchas gracias

1 respuesta
Gif

#436

void incrementRef(int* ptr){
	++(*ptr); // dereferenciamos el puntero e incrementamos el valor.
}
int incrementVal(int val){
	return ++val; // incrementamos valor y lo devolvemos.
}

int main(void){
	int counterStack = 0;
	int* counterHeap = (int*) malloc(sizeof(int)); // obtienes memoria en el Heap
	*counterHeap = 0; // dereferencias e inicializas el valor del puntero
	incrementRef(&counterStack); // pasas por referencia
	incrementRef(counterHeap); // pasas por valor el puntero
	counter = incrementVal(counterStack); // pasas por valor la variable que esta en el Stack
	free(counterHeap); // liberas la memoria reservada que tenias en el Heap.
	return 0;
}
1 respuesta
Overburden

hola gente, me he liao en un ejercicio tonto de estos de teórico/práctico, a ver, el enunciado es: Definir una función que acepte dos argumentos enteros y devuelva un puntero a un entero largo.

#437 gracias por el ejemplo, aun así tuve que buscar alguno más ejemplos para entenderlo, soy torpe.

1 respuesta
herre

#438

long *fun(int a, int b)
{
        /* ... */
}
1
7 días después
Vireca

De la segunda a la primera leccion hay un paso gigante. Ya me costo hacer las operaciones y ahora tengo que calcular la hipotenusa y el angulo de un triangulo :psyduck:

Para alguien que no tiene NPI de ningun lenguaje que me recomiendas? Porque me leo las cosas y me quedo igual

1 respuesta
gonya707

#440 programáticamente no deberias tener ningun problema con ese ejercicio si has comprendido lo hecho anteriormente, asi que intuyo que el problema te viene por desconocimiento de las matemáticas qu hay detrás del problema.

no hay mucho que pueda hacer yo ahi... no hagas de momento ese ejercicio, pero con unas nociones básicas de trigonometría deberia bastar

1 respuesta
Vireca

#441 no es por el problema en si, sino por la comprension del lenguaje. Que no tengo mucha idea de pensar en un lenguaje de programacion

Ya te digo que no tengo ni idea de programar y empiezo esto desde 0. No se si tendria que mirarme algun libro para comprender como se piensa con un lenguaje o algo asi

2 respuestas
Gif

#442 mírate Scratch y prueba con eso.

gonya707

#442 hombre, yo escribi el curso desde cero orientandolo siempre a gente que no supiese nada. Si empiezas desde la primera lección y vas avanzando comprendiendo todo lo expuesto no deberias tener problema, si vas con prisas, si.

Y en el caso de que haya algo que no se entiende porque lo he explicado mal o por cualquier cosa siempre puedes consultar tus dudas por aquí, para eso estamos.

Alternativamente puedes intentar comenzar por otro lenguaje más sencillo como indica el caballero de arriba, pero creo que te resultará mucho más productivo comprender C y saber desenvolverte con un lenguaje que se sigue usando actualmente, incluso en entornos profesionales

9 días después
Leos

Tengo que hacer un programa que me diga la cantidad de dias que tiene un mes en el año introducido, lo del año bisiesto me lo coge bien, lo único que no se como hacer es que me imprima los dias que pongo en la funcion num_dias :S

#include <stdio.h>
#include <stdlib.h>

int dies;

int num_dias(int año, int mes);
int vicies(int año);

int main(void){
    
int año, mes; printf("\nIntroduce un año: "); scanf("%d", &año); printf("\nIntroduece un mes: "); fflush(stdin); scanf("$d", &mes); printf("\n%d de dias!", num_dias(año, mes)); system("pause"); return 0; } int vicies(int año){ if(any%4==0 && (año%100!=0 || año%400==0)) return 1; return 0; } int num_dies(int año, int mes){
if(mes==1 || mes==3 || mes==5 || mes==7 || mes==8 || mes==10 || mes==12) dias=31; if(mes==2){ if(vicies(año))dias=29; else dias=28; } if(mes==4 || mes==6 || mes==9 || mes==11 ) dias=30; }
3 respuestas
Gif

#445 te falta el return dias;

1 respuesta
Leos

#446 Ya lo había probado, pero si pongo return dias, me sale 0 todo el rato.

gonya707

#445

(int año, int mes)

u mad?

1 respuesta
Leos

#448 Eso es que lo he hecho muy mal no? Solo hemos dado una clase y no me ha quedado nada claro :S

1 respuesta
gonya707

#449 no pongas ñ en el codigo, es a lo que me refiero, abstente a usar solo caracteres del ascii estandar.

Luego es que tienes errores de sintaxis por todos lados, a la funcion num_dias la llamas num_dies en otro sitio, y a año lo llamas any... dale un repaso al codigo

1 respuesta