Ten en cuenta que en las ciencias cualquier problema casi siempere suele tener más de una resoluciones, así que aquí mostraremos lo más óptimo y mejor.
Solución:
No se puede usar break;
de esta manera, debe aparecer dentro del cuerpo del for
círculo.
Hay varias formas de hacer esto, pero no se recomienda ninguna:
-
puede salir del programa con el
exit()
función. Dado que el bucle se ejecuta desdemain()
y no haces nada después de eso, es posible lograr lo que quieres de esta manera, pero como un caso especial. -
Puede establecer una variable global en la función y probarla en el
for
bucle después de la llamada a la función. El uso de variables globales generalmente no es una práctica recomendada. -
puedes usar
setjmp()
ylongjmp()
, pero es como intentar aplastar una mosca con un martillo, puede romper otras cosas y perder la mosca por completo. No recomendaría este enfoque. Además, requiere unjmpbuf
que tendrás que pasar a la función o acceder como variable global.
Una alternativa aceptable es pasar la dirección de un status
variable como argumento adicional: la función puede configurarla para indicar la necesidad de salir del bucle.
Pero, con mucho, el mejor enfoque en C es devolver un valor para probar la continuación, es el más legible.
Según sus explicaciones, no tiene el código fuente para foo()
pero puede detectar algunas condiciones en una función que puede modificar llamada directa o indirectamente por foo()
: longjmp()
saltará desde su ubicación, en lo profundo de las entrañas de foo()
, posiblemente muchos niveles por debajo de la pila de llamadas, hasta el setjmp()
ubicación, omitiendo el código de salida de función regular para todas las llamadas intermediarias. Si eso es precisamente lo que debe hacer para evitar un accidente, setjmp()
/ longjmp()
es una solución, pero puede causar otros problemas como pérdida de recursos, inicialización faltante, estado inconsistente y otras fuentes de comportamiento indefinido.
Tenga en cuenta que su for
el bucle iterará 101
veces porque usas el <=
operador. El idiomático for
usos del bucle for (int i = 0; i < 100; i++)
para iterar exactamente el número de veces que aparece como límite superior (excluido).
break
, me gusta goto
, solo puede saltar localmente dentro de la misma función, pero si es absolutamente necesario, puede usar setjmp
y longjmp
:
#include
#include
jmp_buf jump_target;
void foo(void)
printf("Inside foo!n");
longjmp(jump_target, 1);
printf("Still inside foo!n");
int main(void)
if (setjmp(jump_target) == 0)
foo();
else
printf("Jumped out!n");
return 0;
La llamada a longjmp
causará un salto de regreso a la setjmp
llamar. El valor de retorno de setjmp
muestra si regresa después de establecer el objetivo del salto, o si regresa de un salto.
Producción:
Inside foo!
Jumped out!
Los saltos no locales son seguros cuando se usan correctamente, pero hay varias cosas en las que pensar detenidamente:
- Ya que
longjmp
salta "a través" de todas las activaciones de funciones entre elsetjmp
llamar y ellongjmp
call, si alguna de esas funciones espera poder realizar trabajo adicional después del lugar actual en ejecución, ese trabajo simplemente no se realizará. - Si la activación de la función que llamó
setjmp
ha terminado, el comportamiento no está definido. Cualquier cosa puede suceder. - Si
setjmp
aún no ha sido llamado, entoncesjump_target
no está configurado y el comportamiento no está definido. - Variables locales en la función que llamó
setjmp
puede, en determinadas condiciones, tener valores indefinidos. - Una palabra: hilos.
- Otras cosas, como que los indicadores de estado de punto flotante pueden no conservarse y que existen restricciones sobre dónde puede colocar los
setjmp
llamar.
La mayoría de estos se siguen de forma natural si tiene una buena comprensión de lo que hace un salto no local en el nivel de las instrucciones de la máquina y los registros de la CPU, pero a menos que tenga eso, y Si he leído lo que el estándar C garantiza y no garantiza, le aconsejaría algo de precaución.
(Nota: la pregunta ha sido editada desde que escribí esto originalmente)
Debido a la forma en que se compila C, debe saber dónde ir cuando se llama a la función. Dado que puede llamarlo desde cualquier lugar, o incluso en algún lugar, un descanso no tiene sentido, no puede tener un break;
declaración en su función y haga que funcione así.
Otras respuestas han sugerido soluciones terribles, como establecer una variable global, usar una #define
o saltos largos (!) fuera de la función. Estas son soluciones extremadamente pobres. En su lugar, debe usar la solución que descartó erróneamente en su párrafo de apertura y devolver un valor de su función que indique el estado en el que desea activar una break
en este caso y haga algo como esto:
#include
bool checkAndDisplay(int n)
printf("%dn", n);
return (n == 14);
int main(void)
for (int i = 0; i <= 100; i++)
if (checkAndDisplay(i))
break;
return 0;
Tratar de encontrar formas oscuras de lograr cosas como esta en lugar de utilizar la forma correcta para lograr el mismo resultado final es una forma segura de generar código de calidad terrible que es una pesadilla de mantener y depurar.
Mencionas, oculto en un comentario, que debes usar un void return, esto no es un problema, simplemente pase el parámetro break como un puntero:
#include
void checkAndDisplay(int n, bool* wantBreak)
printf("%dn", n);
if (n == 14)
wantBreak = true;
int main(void)
bool wantBreak = false;
for (int i = 0; i <= 100; i++)
checkAndDisplay(i, &wantBreak);
if (wantBreak)
break;
return 0;
Dado que sus parámetros son de tipo fijo, le sugiero que use una conversión para pasar el puntero a uno de los parámetros, por ejemplo foo(a, b, (long)&out);
Eres capaz de estimular nuestro trabajo fijando un comentario y dejando una valoración te damos la bienvenida.