¿Por qué tiene que especificar el tipo de datos al declarar variables?

41

En la mayoría de los lenguajes de codificación (si no todos) necesita declarar variables. Por ejemplo, en C # si es un campo numérico, entonces

int PhoneNumber

Si estoy usando el idioma inglés normal, no necesito declarar PhoneNumber como int para usarlo. Por ejemplo, si le pido a mi amigo Sam que me dé su número de teléfono, digo:

  

"Sam, dame el número de teléfono"

No diría

  

"Char (20) Sam, dame el número de teléfono internacional"

¿Por qué tenemos que especificar el tipo de datos?

    
pregunta dick smith 21.03.2016 - 00:11

13 respuestas

79
  

En la mayoría de los lenguajes de codificación (si no todos) necesita declarar variables.

     

[…]

     

¿Por qué tenemos que especificar el tipo de datos?

Esas son dos preguntas independientes:

  • ¿Por qué necesitamos declarar variables?
  • ¿Por qué necesitamos declarar tipos?

Por cierto, la respuesta a ambas es: no lo hacemos.

Hay muchos lenguajes de programación tipificados estáticamente en los que no es necesario declarar tipos. El compilador puede inferir los tipos del contexto circundante y el uso.

Por ejemplo, en Scala puedes decir

val age: Int = 23

o simplemente puedes decir

val age = 23

Los dos son exactamente equivalentes: el compilador inferirá que el tipo es Int de la expresión de inicialización 23 .

Del mismo modo, en C♯, puedes decir cualquiera de estos, y ambos significan exactamente lo mismo:

int age = 23;
var age = 23;

Esta función se llama inferencia de tipo , y muchos idiomas además de Scala y C♯ la tienen: Haskell, Kotlin, Ceylon, ML, F♯, C ++, lo que sea. Incluso Java tiene formas limitadas de inferencia de tipos.

En los lenguajes de programación de tipo dinámico, las variables ni siquiera tienen tipos. Los tipos solo existen dinámicamente en tiempo de ejecución, no estáticamente. Solo los valores y expresiones tienen tipos y solo en tiempo de ejecución, las variables no tienen tipos.

Por ejemplo, en ECMAScript:

const age = 23;
let age = 23;

Y, por último, en muchos idiomas, ni siquiera es necesario declarar variables. p.ej. en Ruby:

age = 23

De hecho, el último ejemplo es válido en varios lenguajes de programación. La misma línea de código exacta también funcionaría en Python, por ejemplo.

Entonces,

  • incluso en idiomas tipificados estáticamente donde las variables tienen tipos, no necesariamente tiene que declararlos,
  • en los idiomas tipificados dinámicamente, las variables no tienen tipos, por lo que obviamente no puede incluso declararlos,
  • en muchos idiomas, ni siquiera tiene que declarar variables
respondido por el Jörg W Mittag 21.03.2016 - 01:52
52

Cuando utiliza el lenguaje natural para referirse a la información, no es muy preciso y, en particular, no se comunica mucho con los demás sobre su intención. Se producen problemas similares al intentar hacer matemáticas en lenguaje natural: simplemente no es lo suficientemente preciso.

La programación es compleja; Los errores son muy fáciles de encontrar. Los tipos forman parte de un sistema de controles diseñados para evitar estados de programas ilegales, al detectar condiciones de error. Diferentes idiomas usan tipos de manera diferente: algunos idiomas usan tipos para detectar errores en tiempo de compilación. Casi todos los idiomas tienen alguna noción de tipos incompatibles como error de tiempo de ejecución. Por lo general, un error de tipo indica un error de algún tipo en el programa. Cuando permitimos que los programas continúen a pesar de los errores, es probable que obtengamos respuestas muy malas. Preferimos detener el programa en lugar de obtener respuestas malas o incorrectas.

Dicho de otra manera, los tipos expresan restricciones en el comportamiento del programa. Las restricciones, cuando son aplicadas por algún mecanismo, proporcionan garantías. Tales garantías limitan la cantidad de razonamiento necesario para pensar en el programa, simplificando así la tarea de leer y mantener el programa para los programadores. Sin tipos, y su implicación de herramientas (es decir, el compilador) que detecta errores de tipo, la carga de programación es considerablemente mayor y, por lo tanto, más costosa.

Es cierto que (muchos) los humanos distinguen fácilmente entre un número de teléfono europeo, estadounidense e internacional. Sin embargo, la computadora realmente no "piensa" y, si se le indica, marca un número de teléfono de Estados Unidos en Europa, o viceversa. Los tipos, por ejemplo, son una buena manera de distinguir entre estos casos, sin tener que enseñar a la computadora cómo "pensar". En algunos idiomas, podemos obtener un error de compilación al tratar de mezclar un número de teléfono europeo en un sistema telefónico estadounidense. Ese error nos dice que debemos modificar nuestro programa (quizás convirtiendo el número de teléfono a una secuencia de marcación internacional o, en su lugar, utilizando el número de teléfono en Europa), incluso antes de que intentemos ejecutar el programa.

Además, como la computadora no piensa, el nombre del campo o variable (por ejemplo, phonenumber ), no significa nada para la computadora. Para la computadora, ese nombre de campo / variable es simplemente "blah123". Piense en cómo sería su programa si todas las variables fueran "blahxxx". Yikes Bueno, eso es lo que ve la computadora. Proporcionar un tipo le da a la computadora una idea del significado de la variable que simplemente no puede deducir solo con su nombre.

Además, como dice @Robert, en muchos idiomas modernos no tenemos que especificar tipos tanto como lo hicimos en los viejos tiempos, ya que lenguajes como C # realizan "inferencia de tipo", que es un conjunto de reglas para determinar el tipo adecuado para una variable en contexto. C # solo proporciona inferencia de tipo en variables locales, pero no en parámetros formales o campos de clase o instancia.

    
respondido por el Erik Eidt 21.03.2016 - 01:37
28

Además de las otras respuestas, hay una cosa que debe incluirse. Recuerda que las computadoras son solo bits. Digamos que te doy los bytes:

26 3A 00 FF

¿Qué significa eso ? Se almacena de esta manera en la computadora, pero sin ninguna interpretación, es solo bits . Podrían ser 4 caracteres ascii. Podría ser un entero. Podría ser algunos bytes en una matriz. Podría ser parte de un objeto. Podría ser un puntero a donde el video del gato se está almacenando en búfer. Casi todos los lenguajes de programación, desde el ensamblado en adelante, necesitan algo para saber cómo interpretar los bits para que hagan un cálculo significativo.

Y como la computadora no puede saber el significado de esos bits, necesita que se lo diga, ya sea explícitamente mediante anotaciones de tipo o implícitamente mediante los mecanismos de inferencia de tipo mencionados en las otras respuestas.

    
respondido por el Telastyn 21.03.2016 - 03:32
22

La respuesta a por qué las computadoras necesitan que esta información tenga que ver con Representación de datos .

El nombre del "tipo de datos" es una referencia a las reglas que ayudan a la computadora a almacenar y recuperar información de su estado original de 0 y 1 en la memoria de la computadora.

Por ejemplo, su carácter ASCII normal de 8 bits se almacenará en la memoria de la computadora (RAM o Disco) como 01000001 (el carácter en mayúscula "A", código ASCII 65) o 00001000 (el porcentaje signo), o cualquier combinación de 0 y 1 en esos 8 bits.

Para otro ejemplo, algunos enteros sin signo de 8 bits se pueden almacenar como 00000101 (el número 5) o 00001000 (el número 8)

Observe cómo la representación binaria de 8 y el carácter% pueden ser iguales, pero tienen significados diferentes porque sus tipos son diferentes.

Incluso los idiomas que infieren el tipo de datos, pueden no tener la regla de que "todos los tipos de variables deben ser declarados por el programador", tienen reglas como "si su serie de caracteres está entre comillas, es una cadena "y muchas más reglas para cada tipo de datos.

Entonces, incluso estos necesitan tipos de datos para dar sentido a lo que significan los 0 y los 1, así que pueden, por ejemplo, realizar la función de concatenación de cadenas si intentas "agregar" dos caracteres, o hacer una suma de enteros si intentas agrega dos enteros.

También en tu historia , digamos que no le pediste el número de teléfono a Sam, pero Sam te da un papel que tiene escrito "1123581321". No podría estar seguro de si Sam es solo un fanático de los primeros ocho números de Fibonacci, o si es un número de teléfono. Para hacer una suposición, deberá tener en cuenta el contexto y las señales que tiene disponibles, como quizás le pidió a Sam un número de teléfono hace un día, o la nota dice "Llámame", o si cuenta los dígitos y encuentra coincide con los patrones de la mayoría de los números de teléfono. Solo entonces sabría que es un número de teléfono al que puede llamar y no algunos dígitos que ingresaría en una calculadora.

Tenga en cuenta que estas sugerencias que lo llevaron a adivinar que el número era un número de teléfono son similares a las sugerencias de un lenguaje informático que no requiere declaración para deducir el tipo de valor.

    
respondido por el Peeyush Kushwaha 21.03.2016 - 08:48
10

En algunos idiomas, no es necesario especificar el tipo de datos.

Los idiomas que admiten la inferencia de tipos generalmente pueden determinar el tipo de datos a partir de su uso. Por ejemplo,

var name = "Ali"

se escribe internamente como una cadena, porque el valor está rodeado por comillas.

Algunos idiomas no requieren que usted declare la variable tampoco; la variable se crea cuando se usa por primera vez. Sin embargo, se considera una buena práctica declarar específicamente sus variables, por varias razones importantes; Sobre todo porque hacerlo mejor expresa tu intención.

    
respondido por el Robert Harvey 21.03.2016 - 00:23
9

Porque eso es lo que especifica el diseño del idioma. Entonces, para responder a su pregunta, debemos observar la intención detrás de la escritura explícita en lenguajes como C # y C ++. (Bueno, C # lo hace porque C ++ lo hace porque C lo hace, así que tenemos que ver la intención en ese entonces).

En primer lugar, la tipificación explícita y estática proporciona rigor en la codificación: especificar que una variable sea un número entero significa que el compilador y el software deben sorprenderse y generar un error al asignar un carácter o una cadena a la variable. La escritura dinámica puede causar dolores de cabeza a los incautos (simplemente observe el enfoque de PHP o javascripts para ver la verdad de cosas como matrices y cadenas vacías).

Puede tener estática con la escritura implícita: inicializar una variable como una cadena significa que esa variable solo debería ser una cadena, pero creo que esto puede causar problemas para los humanos que leen el código (tiendo a asumir la escritura dinámica cuando hay es la escritura implícita).

Además, es posible, en algunos idiomas, escribir algo como este pseudocódigo para inicializar una clase desde una entrada de cadena:

PhoneNumber phoneNumber = "(61) 8 8000 8123";

En segundo lugar, la escritura explícita también va de la mano con la asignación de memoria. Un int siempre tiene tantos bytes. Un número de teléfono tiene tantos bytes. El compilador puede asignar un bloque de memoria del tamaño apropiado que luego se puede usar sin tener que ver cuánto espacio necesitará cuando asigne un valor.

PhoneNumber phoneNumber;
...
phoneNumber = "some value from somewhere";

Finalmente, elimina la confusión ... ¿es 123 un entero o un entero sin signo? Necesitan el mismo número de bytes, pero el valor máximo almacenado en las variables de cualquier tipo es muy diferente ...

Esto no es así, digamos que explícito es mejor que implícito, pero el diseño del lenguaje se basa en este tipo de opciones, y C # funcionaría de manera diferente con la escritura implícita. PHP y javascript funcionarían de manera diferente con la escritura explícita.

    
respondido por el HorusKol 21.03.2016 - 01:32
5

Porque Sam es más inteligente que los compiladores. Por ejemplo, cuando dice darme el número de teléfono, no especifica si desea el prefijo del país o el código de área si es el número de trabajo donde solo se requieren los últimos 4 dígitos. Además, si solicita el número de la pizzería local, podrá tratar con la respuesta "pizza4u".

Sam, lo calcula fuera de contexto. Si bien el compilador también puede descifrarlo a partir del contexto, Sam será mejor en eso (y es capaz de interrumpir el proceso para pedir una aclaración).

Hay dos enfoques básicos para los tipos y las variables, o la variable tiene un tipo, en cuyo caso las acciones que no están permitidas por el tipo están prohibidas e impiden la compilación, o el valor tiene un tipo y acciones que no lo están Los permitidos por el tipo se capturan en tiempo de ejecución.

Cada enfoque tiene sus ventajas y desventajas. En general, los escritores de compiladores intentan minimizar las desventajas y maximizar las ventajas. Es por eso que C #, por ejemplo, permite var phoneNumber = GetPhoneNumber(); y deducirá el tipo de número de teléfono de la firma de GetPhoneNumber. Eso significa que debe declarar el tipo para el método, pero no la variable que recibe el resultado. Por otro lado, hay varios tipos de insinuación / ejecución de proyectos para javascript. Todo es un intercambio.

    
respondido por el jmoreno 21.03.2016 - 04:06
3

Es una cuestión de la forma en que se almacenan los datos. Tu interacción con Sam haría una mejor comparación si lo estuvieras preguntando para que pudieras escribirlo pero solo tuviera el papel de ocho caracteres.

  

"Sam, dame el número de teléfono".

     

"5555555555"

     

"Oh, no, me he quedado sin papel. ¡Si hubiera sabido de antemano la cantidad de datos que estaba pidiendo, podría haberme preparado mejor!"

Así que, en cambio, la mayoría de los idiomas te hacen declarar un tipo, por lo que sabrá y preparará con anticipación:

  

"Sam, ¿cuánto tiempo tiene un número de teléfono?"

     

"Diez caracteres".

     

"Bien, entonces déjame conseguir un pedazo de papel más grande. Ahora dame el número de teléfono".

     

"5555555555"

     

"¡Lo tengo! Gracias Sam!"

Se vuelve aún más peludo cuando observa las formas fundamentales reales en que se almacenan los datos. Si eres como yo, tienes un cuaderno con notas variadas, números garabateados, sin contexto ni etiquetas para nada, y no tienes idea de lo que significa tres días después. Esto también es un problema para las computadoras muchas veces. Muchos idiomas tienen tipos "int" (int, long, short, byte) y "float" (float, double). ¿Por qué es necesario?

Bueno, primero veamos cómo se almacena un entero, y generalmente se representa dentro de la computadora. Probablemente sea consciente de que en el nivel básico, todo es binario (1 y 0). Binario es en realidad un sistema numérico que funciona exactamente igual que nuestro sistema numérico decimal. En decimal, cuentas de 0 a 9 (con infinitos ceros iniciales implícitos que no escribes), luego vuelves a 0 e incrementas el siguiente dígito para que tengas 10. Repites hasta que pasas de 19 a 20, repita hasta que pase de 99 a 100, y así sucesivamente.

Binario no es diferente, excepto que en lugar de 0 a 9, cuentas 0 a 1. 0, 1, 10, 11, 100, 101, 110, 111, 1000. Entonces, cuando escribes 9, en la memoria eso es registrado en binario como 1001. Este es un número real. Se puede agregar, restar, multiplicar, etc., exactamente de esa forma. 10 + 1 = 11. 10 + 10 = 100 (pase de 1 a 0 y lleve el 1). 11 x 10 = 110 (y equivalentemente, 11 + 11 = 110).

Ahora en la memoria real (incluidos los registros), hay una lista, una matriz, como se quiera llamar, de bits (1 o 0 'potencial) uno al lado del otro, que es la forma en que mantiene estos bits lógicamente organizados para hacer un número mayor que 1. El problema es, ¿qué haces con los decimales? No puede simplemente insertar una pieza de hardware entre los dos bits en el registro, y costaría demasiado agregar "bits decimales" entre cada par de bits. Entonces, ¿qué hacer?

Usted lo codifica. Generalmente, la arquitectura de la CPU o el software determinará cómo se hace esto, pero una forma común es almacenar un signo (+ o -, generalmente 1 es negativo) en el primer bit del registro, una mantisa (su número cambió como muchas veces debe ser para deshacerse del decimal) para el siguiente número de bits X, y un exponente (el número de veces que tuvo que desplazarlo) para el resto. Es similar a la notación científica.

Escribir le permite al compilador saber lo que está viendo. Imagine que almacenó el valor 1.3 en el registro 1. Aquí presentamos nuestro propio esquema de codificación de fantasía, 1 bit para signo, 4 para mantisa, 3 para exponente (1 bit para signo, 2 para magnitud). Este es un número positivo, por lo que el signo es positivo (0). Nuestra mantisa sería 13 (1101) y nuestro exponente sería -1 (101 (1 para negativo, 01 = 1)). Así que almacenamos 01101101 en el registro 1. Ahora no escribimos esta variable, así que cuando el tiempo de ejecución se va a utilizar, dice "claro, este es un número entero, por qué no", así que cuando se imprime el valor vemos 109 (64 + 32 + 8 + 4 + 1), que obviamente no está bien.

Sin embargo, no todos los idiomas requieren que escribas explícitamente. C # tiene una palabra clave "var" que hace que el tipo de una variable se interprete en tiempo de compilación, y otros lenguajes como Javascript se escriben de forma totalmente dinámica, hasta el punto en que puede almacenar un número entero en una variable, luego asignarlo a un booleano. asignarlo de nuevo a una cadena y el idioma realiza un seguimiento de todo.

Pero es mucho más fácil para el compilador, el intérprete o el tiempo de ejecución, ya menudo resulta en un programa más rápido, ya que no tiene que gastar recursos valiosos en la clasificación de todo, para preguntarle a usted, el programador, qué tipo de datos le estás dando.

    
respondido por el Devsman 21.03.2016 - 18:24
2

Hay lenguajes de programación donde no tiene que declarar tipos de datos para sus variables. Incluso hay lenguajes de programación donde no tienes que declarar variables de antemano; puedes simplemente usarlos , inmediatamente.

El problema de no declarar nombres de variables es que si accidentalmente escribe incorrectamente el nombre de una variable, ahora ha creado accidentalmente una nueva variable sin relación alguna. Así que cuando ejecutas tu programa, no puedes entender por qué el infierno que la variable que configuraste de repente no tiene nada ... Hasta que, después de muchas horas de depuración, te das cuenta de que escribiste el maldito nombre equivocado GRRR !!

Así que lo hicieron, así que tienes que declarar los nombres de variables que usarás de antemano. Y ahora, cuando escribe un nombre incorrecto, obtiene un error en tiempo de compilación, que le indica inmediatamente exactamente dónde está el error, incluso antes de que se ejecute su programa. ¿No es eso mucho más fácil?

El mismo trato con los tipos de datos. Hay lenguajes de programación donde no tienes que declarar qué tipo de cosas deberían ser. Si tiene una variable customer que en realidad es solo el nombre de un cliente, no todo el objeto del cliente, tratar de obtener la dirección del cliente desde una cadena ordinaria simple ... no va a funcionar. El punto completo de la escritura estática es que el programa no se compilará; se quejará en voz alta, señalando el lugar exacto donde está el problema. Eso es mucho más rápido que ejecutar tu código y tratar de averiguar por qué demonios no funciona.

Todas estas son características para decirle al compilador lo que pretendía hacer, para que pueda verificar lo que realmente hizo y asegurarse de que tenga sentido. Eso hace posible que el compilador automáticamente localice los errores por usted, lo cual es un gran problema.

(Lejos del pasado lejano, no tuvo que declarar subrutinas . Solo haría GOSUB a un número de línea en particular. Si quisiera pasar información entre las subrutinas, lo haría establezca variables globales particulares, llame a su subrutina y luego inspeccione otras variables cuando se devuelva la subrutina. Pero eso hace que sea terriblemente fácil olvidarse de inicializar uno de los parámetros. Así que ahora casi todos     

respondido por el MathematicalOrchid 21.03.2016 - 15:36
1
  

Si estoy usando el idioma inglés normal, no necesito declarar PhoneNumber como int para usarlo. Por ejemplo, si le pido a mi amigo Sam que me dé su número de teléfono, digo:

     

"Sam, dame el número de teléfono"

     

No diría >

     

"Char (20) Sam, dame el número de teléfono internacional"

     

¿Por qué tenemos que especificar el tipo de datos?

Vaya a MathOverflow o Ciencias de la computación teórica y lea por un tiempo para tener una idea de cómo los humanos se comunican entre sí cuando quieren asegurarse de que no hay posibilidad de malentendidos. O lea el estándar para algunos lenguajes de programación maduros.

Encontrará que la definición de los tipos de valores permitidos para un término es parte de una práctica de comunicaciones realmente precisa, incluso de persona a persona.

Lo que has notado es que las interacciones diarias son bastante regulares y las humanas son bastante tolerantes a los fallos, por lo que el conocimiento compartido de los participantes generalmente evita los malentendidos sobre los números de teléfono.

¿Pero alguna vez has intentado quitar un número de teléfono de alguien en otro país? ¿Te dijeron explícitamente cuántas veces debes presionar cero para llegar al direccionamiento internacional? ¿Te dijeron su código de país? ¿Lo reconociste como tal? ¿Cuántos dígitos esperabas? Cuanto obtuviste? ¿Sabías cómo agrupar los dígitos? ¿O incluso si la agrupación tiene importancia?

De repente, el problema es mucho más difícil y es probable que tenga mucho más cuidado para verificar explícitamente que el número recibido se entendió de la forma en que lo hizo el remitente.

    
respondido por el dmckee 22.03.2016 - 06:47
0

Otra razón para declarar tipos es la eficiencia. Mientras que un entero se puede almacenar en 1 byte, o 2 bytes, o 4, un programa que usa una gran cantidad de variables puede usar 4 veces la memoria necesaria, dependiendo de lo que se esté haciendo. Solo el programador sabe si un espacio de almacenamiento más pequeño es viable, por lo que puede decirlo declarando el tipo.

Además, los objetos tipificados dinámicamente permiten muchos tipos posibles, sobre la marcha. Eso podría incurrir en cierta sobrecarga "bajo el capó", ralentizando el programa en comparación con quedarse con un tipo todo el tiempo.

    
respondido por el donjuedo 21.03.2016 - 18:55
0

Varios lenguajes de programación temprana (especialmente Fortran) no requerían que declararas variables antes de usar.

Esto llevó a una serie de problemas. Uno realmente obvio es que el compilador ya no puede detectar errores tipográficos simples de manera tan confiable. Si tiene un código que se supone que modifica una variable existente, pero tiene un error tipográfico, todavía tiene un código perfectamente legítimo que acaba de crear (y asignó un valor a) una nueva variable:

longVariableName = 1

// ...

longVaraibleName = longvariableName + anotherLongVariableName

Ahora, viendo esto de forma aislada, como ya he mencionado un error tipográfico como la fuente del problema, probablemente sea bastante fácil encontrar el error tipográfico y el problema aquí. En un programa largo, donde esto está enterrado en medio de muchos otros códigos, es mucho más fácil pasarlo por alto.

Incluso en la actualidad con muchos idiomas tipificados dinámicamente, aún puede obtener el mismo problema básico con bastante facilidad. Algunos tienen alguna facilidad para advertirte si asignas una variable, pero nunca la lees (que heurísticamente detecta bastantes problemas como este), mientras que otros no tienen esas cosas.

    
respondido por el Jerry Coffin 21.03.2016 - 19:03
0

Cuando declara cualquier variable, se asigna algún espacio en la memoria, pero la máquina (en este caso, la computadora) aún no sabe cuánto espacio debe asignarse para esa variable.

Ejemplo: - crea un programa que le pide al usuario que ingrese cualquier número, en este caso debe especificar un tipo de datos para almacenar ese número; de lo contrario, la máquina no puede juzgar por sí misma que debe asignar 2 bytes o 2 gigabytes , si intenta realizar la asignación por sí mismo, puede resultar en un uso ineficiente de la memoria. Por otro lado, si especifica el tipo de datos en su programa, luego de la compilación, la máquina asignará el espacio adecuado según la necesidad.

    
respondido por el Atul170294 21.03.2016 - 19:41

Lea otras preguntas en las etiquetas