Se em uma determinada situação, você tiver uma matriz de caracteres (terminando, é claro, com o caractere nulo) e logo depois, na próxima posição imediata na memória, desejar armazenar 0
como um int não assinado, como o computador diferencia esses dois?
29
pic X occurs m to n depending on v
( e a contagem pode estar em qualquer lugar, não apenas imediatamente antes), mas armazená- la é mais complicada.Respostas:
Não faz.
O terminador de string é um byte que contém todos os 0 bits.
O int não assinado é de dois ou quatro bytes (dependendo do seu ambiente), cada um contendo todos os 0 bits.
Os dois itens são armazenados em endereços diferentes. Seu código compilado executa operações adequadas para seqüências de caracteres no local anterior e operações adequadas para números binários não assinados no último. (A menos que você tenha um bug no seu código ou algum código perigosamente inteligente!)
Mas todos esses bytes parecem iguais à CPU. Os dados na memória (na maioria das arquiteturas de conjuntos de instruções comuns atualmente) não têm nenhum tipo associado a eles. Essa é uma abstração que existe apenas no código-fonte e significa algo apenas para o compilador.
Edição adicionada: como exemplo: é perfeitamente possível, até comum, executar aritmética nos bytes que compõem uma sequência. Se você tiver uma sequência de caracteres ASCII de 8 bits, poderá converter as letras entre maiúsculas e minúsculas adicionando ou subtraindo 32 (decimal). Ou, se você estiver traduzindo para outro código de caractere, poderá usar seus valores como índices em uma matriz cujos elementos fornecem a codificação de bits equivalente no outro código.
Para a CPU, os caracteres são realmente inteiros extra-curtos. (oito bits cada, em vez de 16, 32 ou 64.) Para nós, humanos, seus valores estão associados a caracteres legíveis, mas a CPU não faz ideia disso. Também não sabe nada sobre a convenção "C" de "byte nulo termina uma string" (e, como muitos observaram em outras respostas e comentários, há ambientes de programação nos quais essa convenção não é usada) .
Para ter certeza, existem algumas instruções no x86 / x64 que tendem a ser muito usadas com cadeias de caracteres - o prefixo REP, por exemplo - mas você pode usá-las também em uma matriz de números inteiros, se atingirem o resultado desejado.
fonte
Em resumo, não há diferença (exceto que um int tem 2 ou 4 bytes de largura e um char apenas 1).
O fato é que todas as bibliotecas modernas usam a técnica terminator nula ou armazenam o comprimento de uma string. E em ambos os casos, o programa / computador sabe que chegou ao final de uma string quando lê um caractere nulo ou lê quantos caracteres o tamanho indica.
Problemas com esse início quando o terminador nulo está ausente ou o comprimento está errado, pois o programa começa a ler da memória que não deveria.
fonte
Não há diferença. O código da máquina (montador) não possui tipos de variáveis, mas o tipo dos dados é determinado pela instrução.
Um exemplo melhor seria
int
efloat
, se você tiver 4 bytes na memória, não há informações sobre se é umint
ou umfloat
(ou algo completamente diferente); no entanto, existem 2 instruções diferentes para adição de número inteiro e adição de número flutuante, portanto, se a adição de número inteiro A instrução é usada nos dados, então é um número inteiro e vice-versa.O mesmo com as strings, se você possui um código que, digamos, olha para um endereço e conta bytes até atingir um
\0
byte, você pode pensar nele como uma função que calcula o comprimento da string.É claro que programar como esse seria uma loucura completa, por isso temos linguagens de nível superior que compilam com código de máquina e quase nenhum programa diretamente no assembler.
fonte
A resposta científica de uma única palavra seria: metadados.
Os metadados informam ao computador se alguns dados em um determinado local são int, uma string, código de programa ou o que for. Esses metadados podem fazer parte do código do programa (como Jamie Hanrahan mencionou) ou podem ser armazenados explicitamente em algum lugar.
As CPUs modernas costumam distinguir entre regiões de memória atribuídas ao código do programa e regiões de dados (por exemplo, o NX Bit https://en.wikipedia.org/wiki/NX_bit ). Algum hardware exótico também pode distinguir entre cadeias e números, sim. Mas o caso usual é que o Software cuida desse problema, apesar de metadados implícitos (no código) ou explícitos (as VMs orientadas a objetos geralmente armazenam os metadados (informações de tipo / classe) como parte dos dados (objeto)) .
Uma vantagem de não distinguir entre diferentes tipos de dados é que algumas operações se tornam muito simples. O subsistema de E / S não precisa necessariamente saber se os dados dos quais apenas lê ou grava no disco são realmente código de programa, texto ou números legíveis por humanos. São apenas bits que são transportados pela máquina. Deixe o código do programa lidar com os problemas de digitação sofisticados.
fonte
Não faz. Faz você!
Ou seu compilador / intérprete.
Se as instruções solicitarem ao computador para adicionar o
0
número, isso será possível. Se eles disserem ao computador para parar para imprimir dados depois de chegar ao0
, como um '\0'
char ' , ele fará isso.Os idiomas têm mecanismos para garantir como tratar os dados. Em C, as variáveis têm tipos, como
int
,float
echar
, e o compilador gera instruções corretas para cada tipo de dados. Mas C permite converter dados de uma variável para outra variável de tipo diferente, até um ponteiro pode ser usado como um número. Para o computador, é tudo como qualquer outro.fonte
Um caractere nulo é um byte e um int não assinado é dois bytes.
fonte