Si en una situación dada, tiene una serie de caracteres (que termina, por supuesto, con el carácter nulo) y justo después de eso, en la siguiente posición inmediata en la memoria, desea almacenar 0
como un int sin signo, ¿cómo diferencia la computadora entre estos ¿dos?
29
pic X occurs m to n depending on v
( y el conteo puede estar en cualquier lugar, no solo inmediatamente antes), pero almacenarlo es más complicado.Respuestas:
No lo hace.
El terminador de cadena es un byte que contiene todos los 0 bits.
El int sin signo tiene dos o cuatro bytes (dependiendo de su entorno), cada uno de los cuales contiene todos los 0 bits.
Los dos elementos se almacenan en diferentes direcciones. Su código compilado realiza operaciones adecuadas para cadenas en la ubicación anterior y operaciones adecuadas para números binarios sin signo en la última. (¡A menos que tenga un error en su código o algún código peligrosamente inteligente!)
Pero todos estos bytes tienen el mismo aspecto para la CPU. Los datos en memoria (en la mayoría de las arquitecturas de conjuntos de instrucciones comunes actualmente) no tienen ningún tipo asociado. Esa es una abstracción que existe solo en el código fuente y significa algo solo para el compilador.
Edición agregada: como ejemplo: es perfectamente posible, incluso común, realizar operaciones aritméticas en los bytes que forman una cadena. Si tiene una cadena de caracteres ASCII de 8 bits, puede convertir las letras en la cadena entre mayúsculas y minúsculas sumando o restando 32 (decimal). O si está traduciendo a otro código de caracteres, puede usar sus valores como índices en una matriz cuyos elementos proporcionan la codificación de bits equivalente en el otro código.
Para la CPU, los caracteres son realmente enteros extra cortos. (ocho bits cada uno en lugar de 16, 32 o 64). Para nosotros, los humanos, sus valores están asociados con caracteres legibles, pero la CPU no tiene idea de eso. Tampoco sabe nada acerca de la convención "C" de "byte nulo termina una cadena" (y, como muchos han señalado en otras respuestas y comentarios, hay entornos de programación en los que esa convención no se utiliza en absoluto) .
Para estar seguros, hay algunas instrucciones en x86 / x64 que tienden a usarse mucho con cadenas, el prefijo REP, por ejemplo, pero también puede usarlas en una matriz de enteros, si logran el resultado deseado.
fuente
En resumen, no hay diferencia (excepto que un int tiene 2 o 4 bytes de ancho y un char solo 1).
La cuestión es que todas las bibliotecas modernas usan la técnica de terminación nula o almacenan la longitud de una cadena. Y en ambos casos, el programa / computadora sabe que alcanzó el final de una cadena cuando lee un carácter nulo o ha leído tantos caracteres como el tamaño le indica.
Los problemas con este inicio comienzan cuando falta el terminador nulo o la longitud es incorrecta, ya que el programa comienza a leer de la memoria que no debería.
fuente
No hay diferencia. El código de máquina (ensamblador) no tiene tipos variables, sino que el tipo de datos está determinado por la instrucción.
Un mejor ejemplo sería
int
yfloat
, si tiene 4 bytes en la memoria, no hay información de si es unaint
o unafloat
(o algo completamente diferente), sin embargo, hay 2 instrucciones diferentes para la suma de enteros y la suma flotante, por lo que si la suma de enteros la instrucción se usa en los datos, luego es un número entero y viceversa.Lo mismo con las cadenas, si tiene un código que, por ejemplo, mira una dirección y cuenta los bytes hasta que alcanza un
\0
byte, puede considerarla como una función que calcula la longitud de la cadena.Por supuesto, una programación como esta sería una locura total, por eso tenemos lenguajes de nivel superior que compilan en código máquina y casi ningún programa en ensamblador directamente.
fuente
La respuesta científica de una sola palabra sería: metadatos.
Los metadatos le dicen a la computadora si algunos datos en una ubicación determinada son int, una cadena, un código de programa o lo que sea. Estos metadatos pueden formar parte del Código del programa (como mencionó Jamie Hanrahan) o pueden almacenarse explícitamente en algún lugar.
Las CPU modernas a menudo pueden distinguir entre regiones de memoria asignadas a código de programa y regiones de datos (por ejemplo, el NX Bit https://en.wikipedia.org/wiki/NX_bit ). Algunos hardware exóticos también pueden distinguir entre cadenas y números, sí. Pero el caso habitual es que el Software se ocupa de este problema, ya sea a través de metadatos implícitos (en el código) o metadatos explícitos (las máquinas virtuales orientadas a objetos a menudo almacenan los metadatos (información de tipo / clase) como parte de los datos (objeto)) .
Una ventaja de no distinguir entre diferentes tipos de datos es que algunas operaciones se vuelven muy simples. El subsistema de E / S no necesariamente necesita saber si los datos que solo lee o escribe en el disco son en realidad códigos de programas, textos o números legibles por humanos. Todo son solo bits que se transportan a través de la máquina. Deje que el código del programa se ocupe de los problemas de escritura sofisticados.
fuente
No lo hace. ¡Hazlo tu!
O tu compilador / intérprete.
Si las instrucciones le dicen a la computadora que agregue el
0
número, lo hará. Si le dicen a la computadora que se detenga para imprimir datos después de llegar al0
, como '\0'
char ' , lo hará.Los idiomas tienen mecanismos para garantizar cómo tratar los datos. En C las variables tienen tipos, como
int
,float
ychar
, y el compilador genera instrucciones correctas para cada tipo de datos. Pero C le permite convertir datos de una variable a otra variable de diferente tipo, incluso un puntero puede usarse como un número. Para la computadora todo son bits como cualquier otro.fuente
Un carácter nulo es un byte y un int sin signo es dos bytes.
fuente