59 - Comando goto


Otro comando que tiene el lenguaje C es el goto. Este comando nos permite saltar en forma incondicional a cualquier otra parte de la misma función.

La sentencia goto no es aconsejada en la metodología de programación estructurada pero su uso en casos especiales nos permite crear código mas conciso.

Un caso común donde se la utiliza es cuando queremos salir de una serie de for anidados a un bloque de la misma función pero fuera de dichos for (tener en cuenta que el comando break solo sale del for que la contiene)

Problema 1:

Definir e inicializar una matriz de 3x3 con valores 0. Implementar la carga por teclado de valores enteros, si se carga en algún momento un cero no permitir ingresar más valores.

Programa: programa197.c

Ver video

#include<stdio.h>
#include<conio.h>

#define FILAS 3
#define COLUMNAS 3

void cargar(int mat[FILAS][COLUMNAS])
{
    int f,c;
    for(f=0;f<FILAS;f++)
    {
        for(c=0;c<COLUMNAS;c++)
        {
            printf("Ingrese elemento [%i,%i]:",f,c);
            scanf("%i",&mat[f][c]);
            if (mat[f][c]==0)
            {
                goto salir;
            }
        }
    }
    return;
    salir: printf("Con un cero se termina la carga de elementos\n");
}

void imprimir(int mat[FILAS][COLUMNAS])
{
    int f,c;
    for(f=0;f<FILAS;f++)
    {
        for(c=0;c<COLUMNAS;c++)
        {
            printf("%i ",mat[f][c]);
        }
        printf("\n");
    }
}


int main()
{
    int mat[3][3]={{0,0,0},
                   {0,0,0},
                   {0,0,0}};
    cargar(mat);
    imprimir(mat);
    getch();
    return 0;
}

Luego de la palabra clave goto debemos indicar el nombre de una sección de nuestra función donde debe seguir el flujo de nuestro programa:

            if (mat[f][c]==0)
            {
                goto salir;
            }

En otra parte de la función que puede estar antes o después del comando goto indicamos el mismo nombre de la etiqueta seguida de dos puntos:

    salir: printf("Con un cero se termina la carga de elementos\n");

En nuestro programa en particular si el operador nunca carga un valor cero luego de terminar la ejecución de los dos for encuentra el comando return saliendo de la función y no ejecutando la instrucción posterior a la etiqueta salir:

void cargar(int mat[FILAS][COLUMNAS])
{
    int f,c;
    for(f=0;f<FILAS;f++)
    {
        for(c=0;c<COLUMNAS;c++)
        {
            printf("Ingrese elemento [%i,%i]:",f,c);
            scanf("%i",&mat[f][c]);
            if (mat[f][c]==0)
            {
                goto salir;
            }
        }
    }
    return;
    salir: printf("Con un cero se termina la carga de elementos\n");
}

Si no disponemos la instrucción return y el operador carga todos los valores distintos a cero al finalizar los dos for ejecuta la función printf sin importar que está precedida por la etiqueta salir.

Si consultamos el código fuente del sistema operativo Linux veremos que utiliza el comando goto en numerosas funciones:

código fuente linux comando goto

Problema propuesto

Solución

programa198.c

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

#define FILAS 5
#define COLUMNAS 10

void cargar(int mat[FILAS][COLUMNAS])
{
    int f,c;
    for(f=0;f<FILAS;f++)
    {
        for(c=0;c<COLUMNAS;c++)
        {
            mat[f][c]=rand()%10 + 1;
        }
    }
}

void imprimir(int mat[FILAS][COLUMNAS])
{
    int f,c;
    for(f=0;f<FILAS;f++)
    {
        for(c=0;c<COLUMNAS;c++)
        {
            printf("%3i ",mat[f][c]);
        }
        printf("\n");
    }
}

void buscar(int mat[FILAS][COLUMNAS])
{
    int f,c;
    int valor;
    printf("Ingrese el valor a buscar:");
    scanf("%i",&valor);
    for(f=0;f<FILAS;f++)
    {
        for(c=0;c<COLUMNAS;c++)
        {
            if (valor==mat[f][c])
            {
                goto encontrado;
            }
        }
    }
    printf("El valor ingresado no esta en la matriz");
    return;
    encontrado:
        printf("El valor ingresado se encuentra en la matriz");
}


int main()
{
    int mat[FILAS][COLUMNAS];
    cargar(mat);
    imprimir(mat);
    buscar(mat);
    getch();
    return 0;
}


Retornar