Como um computador diferencia '\ 0' (caractere nulo) de 'unsigned int = 0'?

29

Se em uma dada situação, você tem uma matriz de caracteres (terminando com o caractere nulo) e logo em seguida, na próxima posição imediata na memória, você quer armazenar 0 como um unsigned int, como o computador diferencia estes dois?

    
por Angelixus 01.10.2018 / 12:15

6 respostas

86

Isso não acontece.

O terminador de cadeia é um byte contendo todos os 0 bits.

O unsigned int tem 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 os mesmos para a CPU. Dados na memória (na maioria das arquiteturas de conjunto de instruções atualmente comuns) não possuem nenhum tipo associado a ela. Essa é uma abstração que existe apenas no código-fonte e significa algo apenas para o compilador.

Edit-added: Como exemplo: É perfeitamente possível, até mesmo comum, realizar aritmética nos bytes que compõem uma string. Se você tiver uma cadeia de caracteres ASCII de 8 bits, poderá converter as letras na cadeia 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 um array cujos elementos fornecem o código de bit equivalente no outro código.

Para a CPU, os caracteres são realmente números 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 tem idéia disso. Ele também não sabe nada sobre a convenção "C" de "null byte ends a string", (e como muitos notaram 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 em x86 / x64 que tendem a ser muito usadas com strings - o prefixo REP, por exemplo - mas você também pode usá-las em uma matriz de números inteiros, se eles atingirem o resultado desejado.

    
por 01.10.2018 / 12:22
5

Em suma, não há diferença (exceto que um int tem 2 ou 4 bytes de largura e um caractere apenas 1).

A coisa é que todas as bibliotecas modernas usam a técnica de terminador nulo ou armazenam o tamanho de uma string. E em ambos os casos, o programa / computador sabe que chegou ao fim de uma string quando leu um caractere nulo ou leu tantos caracteres quanto o tamanho diz.

Problemas com este início quando o terminador nulo está faltando ou o comprimento está errado, então o programa começa a ler da memória que ele não deveria.

    
por 01.10.2018 / 12:27
2

Não há diferença. O código da máquina (montador) não tem tipos de variáveis, em vez disso, o tipo de dados é determinado pela instrução.

Um exemplo melhor seria int e float , se você tem 4 bytes na memória, não há informações se é um int ou um float (ou algo totalmente diferente), no entanto, existem 2 instruções diferentes para adição de inteiro e adição de float, então se a instrução de adição de inteiro é usada nos dados, então é um inteiro, e vice-versa.

Mesmo com strings, se você tiver um código que, digamos, analise um endereço e conte bytes até atingir um %code% byte, você poderá considerá-lo uma função que calcula a duração da string.

É claro que programação como essa seria completa loucura, e é por isso que temos linguagens de nível superior que compilam código de máquina e quase nenhum programa em assembler diretamente.

    
por 02.10.2018 / 12:22
2

A resposta científica de uma única palavra seria: metadados.

Os metadados informam ao computador se alguns dados em um determinado local são um int, uma string, um código de programa ou o que for. Estes metadados podem fazer parte do código do programa (como Jamie Hanrahan mencionou) ou pode ser explicitamente armazenado em algum lugar.

As CPUs modernas podem frequentemente distinguir entre as regiões de memória atribuídas ao código do programa e às regiões de dados (por exemplo, o link NX Bit ). Alguns hardwares exóticos também podem distinguir entre strings e números, sim. Mas o caso comum é que o Software cuida desse problema, seja através de metadados implícitos (no código) ou de metadados explícitos (as VMs orientadas a objeto 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 que apenas lêem ou gravam no disco são, na verdade, código de programa, texto legível para humanos ou números. São apenas bits que são transportados pela máquina. Deixe o código do programa lidar com os problemas de digitação.

    
por 03.10.2018 / 14:07
0

Isso não acontece. Você faz isso!

Ou seu compilador / intérprete.

Se as instruções informarem o computador para adicionar o 0 como um número, ele fará isso. Se eles disserem ao computador para parar para imprimir dados depois de alcançar o 0 , como um ' int' char, ele fará isso.

As linguagens possuem mecanismos para garantir como tratar os dados. Em variáveis C, temos tipos, como float , char e %code% , 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é mesmo um ponteiro para pode ser usado como um número. Para o computador, são todos os bits como qualquer outro.

    
por 03.10.2018 / 23:49
0

Um caractere nulo é um byte e um int não assinado é dois bytes.

    
por 04.10.2018 / 09:35

Tags