Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Wenas!
Tengo una dudilla sobre una operación en C. Se que en lenguaje ensamblador se puede crear "etiquetas" y en cualquier momento de un programa acudir a ellas, parecido a las funciones. Pero, ¿como se puede hacer en C una de esas "etiquetas" y saltar a esa linea cuando yo quiera?
Por ejemplo:
CODIGO; <- Esta seria la etiqueta
if (....lo k sea)
if (....lo k sea)
if (....lo k sea)
"salta a la etiketa CODIGO"
El motivo es por poder salir de una serie de condiciones, que si se han cumplido, pues salte a otra parte de mi programa (pero no que salte a una funcion). No se si ha kedado klara mi duda... Alguien se le ocurre algo??
Muxas gracias!y SaLu2!!
PD: Ah! y otra duda, se como hacer que una funcion devuelva un dato, una variable, pero ¿como hacer para que devuelva 4 valores por ejemplo?
Bueeno..intentare hacerlo sin el goto.. Mirad, a ver si os lo explico lo más klaro posible. Imaginaos un bucle, grande, en el ke corre la mayor parte del programa, y dentro de ese bucle, hay una serie de condiciones, y que si se da el caso en que se cumplan, vuelva al principio de la función (al principio del bucle grande). Ahora que me acuerdo, lo que intenté fue que cuando se cumplieran las condiciones, llamaba a la función para que comenzara desde el principio: void principal (); //El "bucle grande"
{
/* Por aqui habría programa */
if (....)
if (....)
if (....)
principal (); /* Si se cumplen las condic. llama al principal y comenzaría de nuevo no?? */
}
Pues eso no me dejaba compilarlo, supongo que es porque estando en dentro de una función, no puedes llamarla a ella misma otra vez...
El programa es para hacer funcionar una alarma, de ahi que si se da el caso en que se cumplen las condiciones (que se introduzca bien el código) pues apague la sirena, y vuelva al principio (alarma desconectada). Gracias a todos;)!
Qkiyo, más sencillo imposible.
while(...) //bucle principal
{
(...)
if(condicion1)
if(condicion2)
if(condicion3)
continue;
(...)
}
Con el continue ya saltas al inicio del bucle principal.
Otra forma sería hacer programación por estados:
#define ST_REPOSO 0
#define ST_SIRENA 1
#define ...
#define ST_END
main()
{
int state = ST_REPOSO;
while(state != ST_END)
{
switch(state)
{
case ST_REPOSO:
// Condiciones a cumplir para cambiar de estado
break;
case ST_SIRENA:
if(condicion1 && condicion2 && condicion3)
{
ApagarSirena();
state = ST_REPOSO;
}
break;
case ...
...
case ST_END:
break;
default:
state = ST_ERROR; //por si la memoria se corrompe.
break;
}
}
}
Esta forma de programación (máquina de estados) va muy bien para programación de automatas y robots que tienen que tener distintas respuestas según su estado interno (definido por los sensores).
S2
Ranganok Schahzaman
Creo que ya esta solucionado, ese tipo de programación es como usar "banderas" o "flags"?? Es verdad era bastante simple, no se xke me estaba enredando... Gracias de nuevo!
Tampoco hay que pasarse con lo de los gotos y la ruptura de secuencia en C. Es cierto que hay que evitarlo a toda costa pero hay ocasiones (pocas) en que es muy recomendable, por optimización en tiempo de ciclo, por situaciones excepcionales o por otras causas..
Caso uno, real, la primera vez que usé un salto. Además es un setjmp(), que permite saltar a cualquier punto del programa, incluso fuera de una función dejando el stack limpio:
jmp_buf SALTO; // variable necesaria para setjmp()-longjmp();
char getchar ()
{
// aquí leo un caracter del puerto serie, compruebo la paridad etc...
char Car;
Car=input (SERIAL);
if (car & 0x03) ; // codigo de relleno para el ejemplo
// más relleno
if (Car == CTRL_C) longjmp (SALTO, 0); // aquí está el longjmp, para salir de esta función a setjmp () aunque la hayan llamado desde cualquier sitio
}
main()
{
// declaro variables
char pepe;
// aquí declaro el setjmp, al ejecutar longjmop vendrá aquí
setjmp (SALTO);
// inicializo hardware y otras cosas
init_noseque();
init_itracosa();
hago_algo();
while(1) // bucle principal
{
// aqui hago cosas
pepe=getchar();
if (pepe=='a') // proceso el comando 'a'
{
while (no fin);
{
pepe=getchar(); // leo el resto de caracteres
// aqui los proceso...
}
}
}
}
Creo que se ve claro, al recibir en getchar() un carater = CTRL_C salta a setjmp() que es el comienzo de main, lo que equivale a un RESET total del programa, no importa quien haya llamado a getchar(). Evidentemente el programa original que necesitó de esta fucnción era mucho más complejo y no había forma salir a main() desde cada llamada a getchar().
El break es muy util para optimizar los bucles y no duplicar las evaluaciones de las variables. Muchas veces simplifica mucho la lectura de un programa. El continue también.
funcion(char a, char b)
{
int c;
while (a!=0)
{
// hago cosas
if (b==18) // hago sosas distintas
{
// hago sosas distintas
if (c>12)
{
// hago más cosas y acabo
break;
}
}
}
}
Podría haber puesto while (a!=0) && ((b!=18 ) && ()),ero se entiende peor y habría duplicado la comparación de las variables. Así se ve claramente cuando finaliza el bucle: o porque 1!=0 o porque se ejecuta el break si b=18 y c 12.
Estoy de acuerdo en que, en el caso de Qkiyo basta con un continue, pero un solo goto en un probrama no lo va a estropear.
Otra cosa es llenarlo de saltos, entonces no hay quien lo entienda y lo más probable es que se quede pillado en un bucle infinito hasta que rebose el stack...
En resumen, que hay que utilizar de una forma racional los recursos que nos proporciona el lenguaje C, para simplificar y mejorar, no para complicar y empeorar.
Si algo no se lee bién es porque fuera de la ventana de código el editor interpreta los símbolos y los traduce a lo que le da la gana. (b distinto de dieciocho) es (b!=18) Me hace una cara con el 8 y el parántesis!!!