Pregunta de examen en C: ¿Cómo hacer un bucle infinito?

Siguiendo con la pregunta de examen de hace unos días “¿Es un bucle infinito?” hoy toca una nueva pregunta:

¿Cómo modificarías este código para que sí fuera un bucle infinito?

NOTA: No se puede cambiar nada en la línea del for y se deben usar números enteros.

#include <stdio.h>
 
int main() {
	char i;
	for (i=0; i>=0; i++) {
		printf("Soy un bucle infinito (ciclo %d)\n", i);
	}
 
	return 0;
}

Pregunta de examen en C ¿es un bucle infinito?

En el siguiente programa ¿se produce bucle infinito? ¿por qué?

#include <stdio.h>
 
int main() {
	int i;
	for (i=0; i>=0; i++) {
		printf("Soy un bucle infinito\n");
	}
 
	return 0;
}

La respuesta en un par de días.

Curso de programación en C para principiantes

Ejercicios de C resueltos y comentados

Ejercicios de examen de C

Otro de los proyectos que tengo en marcha (suma y sigue) es un libro con ejercicios de examen de C resueltos y comentados. Para hacerlo más completo necesito más ejercicios. Si quieres colaborar puedes enviarme alguno.

¿Qué ganas enviando un ejercicio de examen?

  • Si tu ejercicio se incluye en el libro tendrás una copia gratuita del libro.

Condiciones:

  • No se trata de un servicio para solucionar problemas de examen.
  • No se admiten trabajos de clase, proyectos, ni similares, sólo ejercicios de examen.

Para colaborar rellena este formulario:

Señales en C: Contador de CTRL+C (ejemplo de SIGINT)

Os dejo aquí un sencillo ejemplo de señales que cuenta las veces que el usuario pulsa las teclas CTRL+C. El comportamiento normal al pulsar estas teclas es cerrar el programa, pero aquí asociamos la señal SIGINT (la que se produce cuando pulsamos CTRL+C) a la función contar():

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
 
int num_pulsaciones = 0;  /* Contador de pulsaciones de  CTRL-C */
int bucle = 1;            /* Controlador de salida del bucle de espera */
void terminar_bucle ();   /* Captura la señal de alarma SIGALRM */
void contar ();           /* Captura la señal de interrupción SIGINT */
 
int main () {
    /* Asociamos la señal SIGINT a la función cortar(). La señal SIGINT la recibe el programa cuando
       se pulsa CONTROL+C. */
    signal (SIGINT, contar);
 
    /* Asocia la señal SIGALRM a la función terminar_bucle(). Cuando el programa reciba la señal alarma
       se ejecutará la función terminar_bucle. */
    signal (SIGALRM, terminar_bucle);
 
    printf ("Pulsa varias veces CTRL-C durante 15 segundos.\n");
 
    /* Programamos una alarma para dentro de 15 segundos.
       Cuando pasen 15 segundos este programa
       recibirá una señal SIGALRM. */
    alarm (15);
 
    /* Entramos en un bucle infinito del que solo saldremos 
       cuando la variable bucle cambie su valor. Esto sucederá
       cuando se ejecute la función terminar_bucle(). */
    while (bucle==1);
 
    /* Desactivamos la señal SIGINT porque ya no vamos a contar
       más veces cuando el usuario pulse CTRL+C. */
    signal (SIGINT, SIG_IGN);
 
    printf ("Has pulsado CTRL+C %d veces.\n", num_pulsaciones);
 
    return 0;
    }
 
/* Esta función se ejecutará cuando el proceso reciba la señal SIGALRM al de 15 segundos. */
void terminar_bucle () {
      // Vamos a desactivar la alarma SIGALRM. SIG_IGN hace que se ignore la señal SIGALRM.
      signal (SIGALRM, SIG_IGN);
 
      // Queremos que el bucle infinito que había en la función main se termine. Como hacemos bucle=1
      // el bucle ya no cumple la condición bucle==1 y se termina.
      bucle=0;
      printf ("¡Alarma!\n");
}
 
/* Esta función se ejecuta cada vez que se pulsa CTRL+C (señal SIGINT).
   Cuando se termine esta función el programa seguirá en el punto que se había quedado. */
void contar ()
{
    /* Primero desactivamos la señal SIGINT por si se pulsa CTRL+C 
       mientras se está ejecutando esta función. */
    signal (SIGINT, SIG_IGN);
    printf ("Has pulsado CTRL-C\n");
    num_pulsaciones++;
    // Volvemos a asociar SIGINT con la función cortar() para la próxima vez que el usuario pulse CTRL+C.
    signal (SIGINT, contar);
}

Curso de programación en C para principiantes

Ejercicios de C resueltos y comentados

Calcular los diez primeros elementos de la sucesión de Fibonacci en C

Os dejo aquí otro ejercicio de C que, por supuesto, está incluido en mi libro de ejercicios de C resueltos y comentados.

Se trata del cálculo de los primeros diez elementos de la sucesión de Fibonacci:

#include <stdio.h>
 
int main() {
    int n1, n2, numero, i;
 
    n1 = 0;
    n2 = 1;
 
    printf("0 1 ");
    for( i=0; i<8; i++) {
        numero = n1 + n2;
        printf( "%d ", numero );
        n1 = n2;
        n2 = numero;
    }
 
    return 0;
}

Comprobar si una palabra es un palíndromo en C

Con este sencillo programa escrito en C podemos comprobar si una palabra es un palíndromo (una palabra que se lee igual tanto del derecho como del revés). Esta versión la he hecho usando punteros para el acceso a los elementos de la cadena:

#include <stdio.h>
#include <string.h>
 
int main()
{
    char palabra[20];
    int i, j;
    int palindromo = 1;
    printf("Escribe una cadena: ");
    fflush(stdout);
    gets(palabra);
    j=strlen(palabra)-1;
    for(i=0; i<strlen(palabra)/2; i++, j--) {
        printf("Comprobando %c==%c\n", *(palabra+i), *(palabra+j));
        if (*(palabra+i)!=*(palabra+j)) {
            palindromo = 0;
            break;
        }
    }
    if (palindromo)
        printf("\nEs un palíndrimo.\n");
    else
        printf("\nNo es un palíndrimo.\n");
 
    return (0);
}

Comprobar si un número es primo en C

Aquí os dejo un ejemplillo de cómo se comprueba si un número es primo en C:

#include <stdio.h>
 
int main() {
	int numero, i;
	char es_primo = 1;
 
	i = 2;
 
	printf("Introduce un número: ");
	fflush(stdout);
	scanf("%d", &numero);
 
	while( i<=numero/2 && es_primo==1 ) {
		printf("Comprobando el %d.\n", i);
		if( numero % i == 0 ) {
			printf("%d es divisible al menos 
				por %d, por lo tanto no es
				primo.\n", numero, i);
			es_primo = 0;
		}
		i++;
	}
	if(es_primo)
		printf("%d es número primo.\n", numero);
 
	return 0;
}

Procesos en C: Ejemplo de fork() y wait()

Os pongo aquí otro ejemplo de los que uso en las clases de C. El enunciado del ejercicio es el siguiente:

EJERCICIO 3:

Escribir un programa que cree un hijo. El hijo debe escribir “Soy el hijo” diez veces. El padre debe escribir “Soy el padre” diez veces.
El padre debe esperar a que termine el hijo y mostrar el mensaje “Mi proceso hijo ya ha terminado”.

Usar un switch. No usar semáforos.

PREGUNTAS EJERCICIO 3:

1) ¿Qué proceso terminará primero? ¿Por qué?

#include 
int main() {
	int pid;
	int i;
	int estado;
 
	pid = fork();
 
	switch(pid)
	{
		case -1: // Si pid es -1 quiere decir que ha habido un error
			perror("No se ha podido crear el proceso hijo\n");
			break;
		case 0: // Cuando pid es cero quiere decir que es el proceso hijo
			for(i=0; i&lt;10; i++)
				printf("Soy el hijo\n");
			break;
		default: // Cuando es distinto de cero es el padre
			for(i=0; i&lt;10; i++)
				printf("Soy el padre\n");
			// La función wait detiene el proceso padre y se queda esperando hasta
			// que termine el hijo
			wait(estado);
			printf("Mi proceso hijo ya ha terminado.\n");
			break;
	}
 
}

RESPUESTAS A LAS PREGUNTAS DEL EJERCICIO 3

1) El proceso hijo terminará siempre el primero. La razón es que hemos añadido la función wait() que obligará al padre a esperar al hijo siempre.

Curso de programación en C para principiantes

Ejercicios de C resueltos y comentados

QT+Mysql (3ª parte): Conectando a una base de datos MySQL

Siguiendo con este minicurso de utilización de MySQL con QT vamos a ver un ejemplo de cómo conectar a una base de datos MySQL:

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QLabel resultado("");
    if (QSqlDatabase::isDriverAvailable("QMYSQL")) {
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("localhost");
        db.setDatabaseName("nombreBD");
        db.setUserName("usuarioBD");
        db.setPassword("claveBD");
        if ( db.open() )
           resultado.setText("Bien, base de datos cargada");
        else {
             QSqlError mensaje = db.lastError();
            resultado.setText(mensaje.text());
            }
    }
    else
        resultado.setText("No hay driver");
    resultado.show();
    return app.exec();
}

No creo necesario indicar (pero por si acaso lo hago) que hay que sustituir los valores: nombreBD, usuarioBD y claveBD por los valores adecuados.

Se puede indicar al programa que se conecte a un puerto diferente del habitual mediante:

        db.setPort(3306);

QT+MySQL (2ª parte): Comprobar si está disponible el driver MySQL para QT

Una sencilla aplicación que nos permite comprobar si está disponible el driver MySQL para usarlo con QT.

#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QLabel resultado("");
    if (QSqlDatabase::isDriverAvailable("QMYSQL")) {
       resultado.setText("Driver Mysql disponible");
    }
    else
        resultado.setText("Mala suerte, driver Mysql NO disponible");
    resultado.show();
    return app.exec();
} 

y para compilar no hay que olvidar editar el fichero *.pro y añadir la línea:

qt += sql

En este sencillo programa todo el trabajo importante recae sobre la función estática isDriverAvailable (de la clase QSqlDatabase), que es la que comprueba si está disponible el driver.