programación programacion platzi mejor lenguaje cuál cual java c language-agnostic programming-languages switch-statement

java - cuál - mejor lenguaje de programacion platzi



¿Existe un lenguaje de programación con un mejor enfoque para las declaraciones de interrupción del interruptor? (17)

Ada no tiene trampa, y requiere que todos los valores se manejen explícitamente, o se agregue una cláusula de "otros" para manejar el resto.

La sentencia CASE de SQL tampoco es importante. XSLT tiene que no fracasa.

Parece ser que los lenguajes C y derivados tienen la caída. Es bastante insidioso, y el único uso real que he visto es implementar el dispositivo de duff .

http://www.adaic.org/whyada/intro4.html

Es la misma sintaxis en demasiados idiomas:

switch (someValue) { case OPTION_ONE: case OPTION_LIKE_ONE: case OPTION_ONE_SIMILAR: doSomeStuff1(); break; // EXIT the switch case OPTION_TWO_WITH_PRE_ACTION: doPreActionStuff2(); // the default is to CONTINUE to next case case OPTION_TWO: doSomeStuff2(); break; // EXIT the switch case OPTION_THREE: doSomeStuff3(); break; // EXIT the switch }

Ahora todo lo que sabe es que se requieren declaraciones de break , porque el switch continuará al siguiente case cuando falte la instrucción de break . Tenemos un ejemplo de eso con OPTION_LIKE_ONE , OPTION_ONE_SIMILAR y OPTION_TWO_WITH_PRE_ACTION . El problema es que solo necesitamos este "salto al siguiente caso" muy, pero muy raramente. Y muy a menudo ponemos break al final del case .

Es muy fácil para un principiante olvidarlo. Y uno de mis profesores de C incluso nos lo explicó como si fuera un error en el lenguaje C (no quiero hablar de ello :)

Me gustaría preguntar si hay algún otro idioma que no conozca (o que haya olvidado) que maneje el interruptor / estuche de esta manera:

switch (someValue) { case OPTION_ONE: continue; // CONTINUE to next case case OPTION_LIKE_ONE: continue; // CONTINUE to next case case OPTION_ONE_SIMILAR: doSomeStuff1(); // the default is to EXIT the switch case OPTION_TWO_WITH_PRE_ACTION: doPreActionStuff2(); continue; // CONTINUE to next case case OPTION_TWO: doSomeStuff2(); // the default is to EXIT the switch case OPTION_THREE: doSomeStuff3(); // the default is to EXIT the switch }

La segunda pregunta: ¿hay algún significado histórico de por qué es así en C? ¿Se puede continuar con el siguiente caso que se usó con mucha más frecuencia de la que usamos estos días?


Aquí está la respuesta: this

Se llama declaración directa ( continue en el ejemplo) y existe en los siguientes idiomas:
Ve, perl, c #

En C # no se compilará sin una goto case break o goto case (excepto cuando no hay acción previa).



Creo que la respuesta a su pregunta de por qué es así se centra en dos comportamientos, ambos relacionados con el código de ensamblaje generado desde la fuente C.

La primera es que, en ensamblaje, se ejecuta la instrucción actual y, a menos que haya un salto o alguna otra instrucción de control de flujo, se ejecutará la instrucción en la siguiente dirección. Realizar una compilación ingenua de la sentencia de conmutación a ensamblado generaría un código que simplemente comenzaría a ejecutar la primera instrucción, que sería para ver si había una condición coincidente ...

El segundo motivo relacionado es la noción de una tabla de derivación o una lista de saltos . Básicamente, el compilador puede tomar lo que sabe sobre su valor y crear un código de máquina extremadamente eficiente para la misma cosa. Tomemos, por ejemplo, una función simple como atoi que convierte una representación de cadena de un número y la devuelve en forma de entero. Simplificando las cosas para que sean compatibles con un solo dígito, podría escribir un código similar a este:

int atoi(char c) { switch (c) { case ''0'': return 0; case ''1'': return 1; // .... } }

El compilador ingenuo tal vez simplemente convertiría eso en una serie de bloques if / then, lo que significa que se tomaría una cantidad sustancial de ciclos de CPU para el número 9, mientras que 0 regresa casi inmediatamente. Usando una tabla de derivación, el compilador podría emitir algún ensamblado [psuedo] que inmediatamente "saltaría" a la cláusula de retorno correcta:

0x1000 # stick value of c in a register 0x1004 # jump to address c + calculated offset # example ''0'' would be 0x30, the offset in for this sample # would always be 0x0FD8... thus 0x30 + 0x0FD8 = 0x1008 0x1008 # return 0

Disculpa: mi asamblea y habilidades en C están bastante oxidadas. Espero que esto ayude a aclarar las cosas. 0x


De this artículo, puedo enumerar algunos idiomas que no requieren una declaración de break :

  1. Ada (sin caída)
  2. Eiffel (sin caída)
  3. Pascal (sin caída)
  4. Ir - a fallthrough
  5. Perl - continue
  6. Ruby (sin caída)
  7. VB, VBA, VBS, VB.NET (sin interrupción)
  8. Para ser continuado por otra persona ...

Tu segunda pregunta es bastante interesante. Suponiendo que solo C, creo que esta decisión mantiene el lenguaje cohesionado. Ya que break es un salto , debe estar escrito explícitamente.


El OP habla de "fracasar", pero muy pocas veces me ha mordido eso.

Muchas, muchas veces, sin embargo, he sido mordido por diseños que no son extensibles. A saber, las declaraciones de "switch (kbHit)", con unos pocos cientos de llaves ahí, que son una pesadilla de mantenimiento, y una ubicación frecuente de "métodos de dios", y pilas gigantes de código de espagueti.

El uso del interruptor es a menudo un signo de una mala programación orientada a objetos. Como respondió otra persona, "2 usos de Switch en 48 archivos de origen", en una de sus aplicaciones, muestra a un programador que no depende en gran medida de esta construcción. Por su métrica, supongo que probablemente sea al menos un buen programador estructurado, y que probablemente también comprenda OOP / OOD.

Los programadores OOP (no necesariamente C ++), e incluso los usuarios puros de C que no tienen una técnica de descripción de objetos forzada, podrían implementar un contenedor de "inversión de control" que publique un "toque de tecla" y permita a los suscriptores conectar sus controladores para "en el código del teclado x". Esto puede hacer que leer tu código sea mucho más fácil.


En lenguajes orientados a objetos usas el patrón de Cadena de Responsabilidad . La forma en que se implementa puede variar. Lo que está describiendo en su ejemplo, es mezclar una máquina de estados con un comportamiento abusando de una instrucción switch. Para su ejemplo particular, un patrón de Cadena de Responsabilidad con el parámetro que la cadena evalúa como un patrón de State , que muta a medida que avanza en la cadena, sería la implementación apropiada.


La coincidencia de patrones de Scala creo que es una gran mejora en estos casos. :)

object MatchTest2 extends Application { def matchTest(x: Any): Any = x match { case 1 => "one" case "two" => 2 case y: Int => "scala.Int" } println(matchTest("two")) }

Muestra de scala-lang.org


Lima lo hace así:

if someValue == ?1 :: OPTION_ONE: fall OPTION_LIKE_ONE: fall OPTION_ONE_SIMILAR: doSomeStuff1[] ;; the default is to EXIT the switch OPTION_TWO_WITH_PRE_ACTION: doPreActionStuff2[] fall ;; fall through to the next case OPTION_TWO: doSomeStuff2[] OPTION_THREE: doSomeStuff3[]


Más idiomas sin un solo error:

XSLT JSTL Algol PL / 1


Oye, no te olvides de la evaluación de COBOL:

EVALUATE MENU-INPUT WHEN "0" PERFORM INIT-PROC WHEN "1" THRU "9" PERFORM PROCESS-PROC WHEN "R" PERFORM READ-PARMS WHEN "X" PERFORM CLEANUP-PROC WHEN OTHER PERFORM ERROR-PROC END-EVALUATE.


PASCAL no tiene caída


Pura especulación, pero:

De vez en cuando escribo C o Java en el que digo algo como:

switch (tranCode) { case ''A'': case ''D'': case ''R'': processCredit(); break; case ''B'': case ''G'': processDebit(); break; default: processSpecial(); }

Es decir, uso deliberadamente el salto para permitir que varios valores activen la misma operación.

Me pregunto si esto es lo que pensaron los inventores de C cuando crearon la declaración SWITCH, que este sería el uso normal.


Python no tiene uno en absoluto.

Tomé un poco de tiempo para acostumbrarme pero tengo algunos recuerdos horrendos buscando a través de bloques de switch masivos en mis días de C #. Estoy mucho más feliz sin eso.


Tcl no se cae automáticamente.


Y VB .NET lo maneja un poco más de la forma en que espera que funcione.

Select Case i Case 1 to 3 DoStuff(i) Case 4,5,6 DoStuffDifferently(i) Case Is >= 7 DoStuffDifferentlyRedux(i) Case Else DoStuffNegativeNumberOrZero(i) End Select

No hay caída en absoluto, sin la posibilidad de usar un Goto


los idiomas son demasiado y no puedo responder con seguridad de que no existe tal lenguaje, siempre que sea una "derivada" de C en la sintaxis, porque existen otros idiomas que usan una sintaxis diferente y donde el caso no "continúa" existe naturalmente, por ejemplo Fortran. No sé idiomas que usan un "continuar" explícito para continuar con el siguiente caso.

Creo que es una razón histórica debido a la forma en que tal caso podría programarse en un "nivel bajo". Además, el aspecto sintáctico del caso es el de una etiqueta, y la ruptura funciona como en los bucles, por lo que puedes imaginar un equivalente como este:

if ( case == 1 ) goto lab1; if ( case == 2 ) goto lab2; if ( case == 3 ) goto lab3; //... default: // default goto switch_end; lab1: // do things goto switch_end; // if break is present lab2: // do things, and follow to lab3 lab3: // lab3 stuffs goto switch_end; // ... switch_end: // past all labS.