Por que você precisa especificar o tipo de dados ao declarar variáveis?


41

Na maioria das linguagens de codificação (se não todas), você precisa declarar variáveis. Por exemplo, em C #, se for um campo numérico,

int PhoneNumber

Se eu estiver usando o idioma inglês normal, não preciso declarar PhoneNumbercomo intusá-lo. Por exemplo, se eu pedir ao meu amigo Sam para me dar seu número de telefone, digo:

"Sam me dê o número do telefone"

Eu não diria

"Char (20) Sam me dê o int phoneNumber"

Por que precisamos especificar o tipo de dados?


83
Isso porque Inglês tem digitação implícita - assim yourPhoneNumber é implicitamente digitado como um PhoneNumber - os seres humanos também têm alocação dinâmica de memória ...;)
HorusKol

28
Você e Sam sabem que um número de telefone é composto por dígitos e você ficaria surpreso ao encontrar uma letra nele. Os computadores não precisam e precisam ser informados.
Thorbjørn Ravn Andersen 21/03

16
E quando ouço números como 1-800-JIMBO nos filmes, meu pensamento é: como é esse número ? Oo
muru 21/03

103
Você não deve declarar phoneNumber como int. Na maioria das linguagens de programação, isso excluirá zeros à esquerda.
Aron_dc 21/03

25
@HorusKol: os seres humanos têm não só alocação dinâmica de memória, mas também um coletor de lixo altamente conservativa ...
leftaroundabout

Respostas:


79

Na maioria das linguagens de codificação (se não todas), você precisa declarar variáveis.

[...]

Por que precisamos especificar o tipo de dados?

Essas são duas perguntas independentes:

  • Por que precisamos declarar variáveis?
  • Por que precisamos declarar tipos?

Aliás, a resposta para ambos é: nós não.

Existem muitas linguagens de programação com tipos estatísticos em que você não precisa declarar tipos. O compilador pode inferir os tipos do contexto circundante e do uso.

Por exemplo, em Scala, você pode dizer

val age: Int = 23

ou você poderia apenas dizer

val age = 23

Os dois são exatamente equivalentes: o compilador inferirá o tipo a Intpartir da expressão de inicialização 23.

Da mesma forma, em C♯, você pode dizer um desses, e ambos significam exatamente a mesma coisa:

int age = 23;
var age = 23;

Esse recurso é chamado de inferência de tipo , e muitos idiomas além de Scala e C♯ o possuem: Haskell, Kotlin, Ceilão, ML, F♯, C ++, o nome dele. Até o Java possui formas limitadas de inferência de tipo.

Nas linguagens de programação de tipo dinâmico, as variáveis ​​nem têm tipos. Os tipos existem apenas dinamicamente no tempo de execução, não estaticamente. Somente valores e expressões têm tipos e somente em tempo de execução, as variáveis ​​não têm tipos.

Por exemplo, no ECMAScript:

const age = 23;
let age = 23;

E, finalmente, em muitos idiomas, você nem precisa declarar variáveis. por exemplo, em Ruby:

age = 23

De fato, esse último exemplo é válido em várias linguagens de programação. A mesma linha de código exata também funcionaria em Python, por exemplo.

Tão,

  • mesmo em idiomas de tipo estaticamente, onde as variáveis ​​têm tipos, você não precisa necessariamente declará-las,
  • em linguagens de tipo dinâmico, as variáveis ​​não têm tipos; portanto, você não pode nem mesmo declará-las,
  • em muitos idiomas, você nem precisa declarar variáveis

2
Mais um para explicar tanto inferência tipo e tipagem dinâmica (ligação tardia)
dcorking

36
Essa é uma ótima informação sobre conceitos errôneos por trás da pergunta, mas ainda a deixa sem resposta. A questão, mais propriamente, é por que precisamos especificar o tipo de dados ao declarar variáveis em idiomas que exigem isso? Por que eles foram projetados de maneira? Existem boas respostas para essa pergunta e, embora a elaboração de alternativas amplie os horizontes do OP e seja muito boa, isso não me parece completo.
precisa saber é o seguinte

7
@KRyan: se você quer saber por que um determinado designer de idiomas fez uma escolha de design de determinado idioma, terá que perguntar ao designer de idiomas, receio. Não sei dizer por que os designers de C♯ decidiram contra a inferência de tipo, nem posso dizer por que eles mais tarde mudaram de idéia. O design da linguagem é muito opinativo e muitas vezes se resume ao gosto. Se, OTOH, você deseja saber sobre as compensações específicas envolvidas, a resposta seria basicamente uma reimpressão dos Tipos e Linguagens de Programação do Prof. Pierce, que é muito ampla para o Stack Exchange.
Jörg W Mittag 21/03

2
JörgWMittag: como o @KRyan já disse, a resposta "você não precisa" não é muito interessante (é trivialmente óbvio - muitos idiomas permitem omitir as declarações de tipo em alguns casos). A pergunta "por que você gostaria de declarar tipos" é muito mais interessante e reflete melhor o espírito da pergunta original (sua resposta me lembra a piada: "onde estamos?" - "você está em um balão de ar quente ! " ). Você não precisa saber o que um designer de um idioma específico pensava na época, para fornecer algumas boas razões a favor da declaração de tipo.
JFS

1
@Zaibis: auto i = 1 // i is inferred to type int, vector<int> vec; auto itr = vec.iterator(); // itr is inferred to type vector<int>::iteratore assim por diante. Se você quiser saber exatamente como isso funciona, consulte as especificações.
Jörg W Mittag 23/03

53

Quando você usa a linguagem natural para se referir a informações, ela não é muito precisa e, em particular, não se comunica muito com os outros sobre sua intenção. Problemas semelhantes ocorrem ao tentar fazer contas em linguagem natural: simplesmente não é preciso o suficiente.

A programação é complexa; erros são muito fáceis de encontrar. Os tipos fazem parte de um sistema de verificações projetadas para impedir estados ilegais de programas, detectando condições de erro. Idiomas diferentes usam tipos de maneira diferente: alguns idiomas usam tipos fortemente para detectar erros no tempo de compilação. Quase todos os idiomas têm alguma noção de tipos incompatíveis como um erro de tempo de execução. Geralmente, um erro de tipo indica um erro de algum tipo no programa. Quando permitimos que os programas continuem apesar dos erros, provavelmente obtemos respostas muito ruins. Preferimos interromper o programa em vez de obter respostas ruins ou incorretas.

Dito de outra maneira, os tipos expressam restrições no comportamento do programa. As restrições, quando aplicadas por algum mecanismo, fornecem garantias. Tais garantias limitam a quantidade de raciocínio necessário para pensar sobre o programa, simplificando a tarefa de ler e manter o programa para os programadores. Sem tipos e suas implicações de ferramentas (ou seja, o compilador) que detectam erros de tipo, a carga de programação é consideravelmente maior e, portanto, mais cara.

É verdade que (muitos) humanos distinguem facilmente entre um número de telefone europeu, norte-americano e internacional. No entanto, o computador realmente não "pensa" e, se informado, discaria um número de telefone dos Estados Unidos na Europa ou vice-versa. Tipos, por exemplo, são uma boa maneira de distinguir entre esses casos, sem ter que ensinar ao computador como "pensar". Em alguns idiomas, podemos obter um erro no tempo de compilação ao tentar misturar um número de telefone europeu em um sistema telefônico americano. Esse erro indica que precisamos modificar nosso programa (talvez convertendo o número de telefone em uma seqüência de discagem internacional ou, usando o número de telefone na Europa) antes mesmo de tentar executar o programa.

Além disso, como o computador não pensa, o nome do campo ou variável (por exemplo phonenumber) não significa nada para o computador. Para o computador, esse nome de campo / variável é apenas "blah123". Pense em como seria o seu programa se todas as variáveis ​​fossem "blahxxx". Caramba. Bem, é isso que o computador vê. Fornecer um tipo fornece ao computador uma noção do significado da variável que ele simplesmente não pode deduzir apenas do nome.

Além disso, como diz o @Robert, em muitos idiomas modernos, não precisamos especificar os tipos tanto quanto antigamente, pois idiomas como o C # realizam "inferência de tipo", que é um conjunto de regras para determinar o tipo apropriado para uma variável no contexto. O C # apenas fornece inferência de tipo em variáveis ​​locais, mas não em parâmetros formais ou campos de classe ou instância.


4
RE: a parte triste: é impossível inferir o tipo de membro acessível ao público (campo público, assinatura de método público), porque você não pode prever quando e como ele será usado. Além disso, as anotações de tipo são documentação.
Sergio Tulentsev 21/03

Eu acho que você deve destacar / negrito esta linha: Types are part of a system of checks that ...uma vez que responde diretamente o OP em Why do we have to specify data type at all?..
txtechhelp

Nota: você responde assume que uma linguagem usada para especificar tipos é de alguma forma melhor para evitar erros do que sua linguagem de programação comum. Obviamente, não é assim, por exemplo, considere a linguagem de modelo C ++ que é completa em Turing (e, portanto, permite expressar muitas verificações de erro), mas é quase ilegível em comparação com muitas outras linguagens completas em Turing, como Haskell, Python e até outras partes do C ++ em si. Pergunte a si mesmo por que você não usará a mesma linguagem de programação para expressar as verificações de erro que o restante do programa (existem boas respostas em alguns casos, mas não em todos).
JFS

@SergioTulentsev Isso não é verdade - em F #, você pode ter métodos públicos sem especificar explicitamente seus tipos. O compilador inferirá os tipos de uso dentro do método. Por exemplo, a seguir estão definições válidas de método público: static member add x y = x + y, member x.Append s = x.Text + s. No primeiro caso, xe yserá deduzido ser ints por causa da adição. No segundo caso, eles serão válidos dependendo do tipo de x.Text- se for um string, também sserá um string. Eu concordo que as anotações de tipo são documentação, no entanto.
Roujo 22/03

"Tipos locais implícitos, tipos explícitos de interface" é como muitas pessoas programam, mesmo em idiomas como Haskell que permitem omitir (quase) todos os tipos enquanto o compilador infere tipos estritos. Muitas pessoas não consideram triste quando um idioma impõe essa prática (como o C # faz).
22416 Ben

29

Além das outras respostas, há uma coisa que deve ser incluída. Lembre-se de que os computadores são apenas bits. Digamos que eu lhe forneça os bytes:

26 3A 00 FF

O que isso significa ? É armazenado dessa maneira pelo computador, mas sem nenhuma interpretação, são apenas bits . Pode ter 4 caracteres ascii. Pode ser um número inteiro. Pode haver alguns bytes em uma matriz. Pode ser parte de um objeto. Pode ser um indicador de onde o vídeo do gato está armazenado em buffer. Praticamente todas as linguagens de programação, desde a montagem em diante, precisam de algo para saber como interpretar os bits para fazê-los realizar cálculos significativos.

E como o computador não pode saber o significado desses bits, ele precisa ser informado - explicitamente por meio de anotações de tipo ou implicitamente por mecanismos de inferência de tipo mencionados nas outras respostas.


10
É verdade, mas para realmente confundir sua mente, perceba que o computador nunca é capaz de entender o que esses bits significam - mesmo quando você conta mais anotações de tipo. Suas explicações são transformadas em ainda mais números hexadecimais, para "esclarecer" os primeiros números hexadecimais. O significado é todo criado pelas pessoas para colocar a intenção nos eletrônicos e levá-las a fazer o que pretendemos. Agora vá dizer "obrigado" a um engenheiro. :)
Curinga

1
Passei muitos anos programando em mainframes. Com PL / 1, essa resposta faz muito sentido. Com bastante regularidade, seríamos usados ​​armazenamento baseado em um ponteiro que foi definido como o endereço de outra variável de um tipo de dados diferente para acessar os bytes de uma maneira diferente. Por exemplo, o PL / 1 não suporta um campo numérico binário de 1 byte, mas basearíamos uma variável de 1 caractere no endereço para permitir o armazenamento de uma matriz de 6 bytes armazenando campos binários de 6 bytes (nesse caso, permitindo salvar 6 bytes por endereço - o que era importante quando o armazenamento era caro).
Kickstart #

1
O computador é capaz de entender muitas possibilidades, mas mesmo os compiladores inteligentes precisam de contexto para entender. Não é o mesmo número 0 ou "0". Ou a String "31 de dezembro" será ordenada antes de "1 de maio" tratada como uma String, mas não se tratada como uma Data. Ou pegue 5/2. É 2 como entrada, mas 2,5 como dupla. Além disso, o tipo é uma medida de segurança contra conversões indesejadas. Nulo, NaN e arredondamentos ou estouros também podem se tornar um problema. Linguagens fortes e de tipo estatístico têm algumas vantagens. Por exemplo, o compilador ajuda a detectar problemas durante a refatoração.
Borjab 21/03

1
@Borjab Você quis dizer "É 2 como um número inteiro "?
Richard Everett

1
@ Richardhardverver Certamente isso foi um lapsus. Obrigado, mas tarde demais para editá-lo.
precisa saber é o seguinte

23

A resposta para o motivo pelo qual os computadores precisam dessas informações está relacionada à representação de dados .

O nome do "tipo de dados" é uma referência a regras que ajudam o computador a armazenar e recuperar informações do estado bruto de 0 e 1 na memória do computador.

Por exemplo, seu caractere ASCII de 8 bits comum seria armazenado na memória do computador (RAM ou disco) como 01000001(o caractere maiúsculo "A", código ASCII 65) ou 00001000(o sinal de porcentagem) ou qualquer combinação de 0 e 1 nesses 8 bits.

Por outro exemplo, algum número inteiro não assinado de 8 bits pode ser armazenado como 00000101(o número 5) ou 00001000(o número 8)

Observe como a representação binária de 8 e o caractere% podem ser os mesmos, mas eles significam coisas diferentes porque seus tipos são diferentes.

Mesmo nos idiomas que inferem o tipo de dados, eles podem não ter a regra de que "todos os tipos de variáveis ​​devem ser declarados pelo programador", eles têm regras como "se sua série de caracteres estiver entre aspas, é uma string" e muito mais regras para cada tipo de dados.

Portanto, mesmo esses precisam de tipos de dados para entender o significado dos zeros e zeros, para que eles possam, por exemplo, executar a função de concatenação de strings se você tentar "adicionar" dois caracteres ou fazer adição de números inteiros se tentar adicionar dois inteiros. .

Também na sua história , digamos que você não pediu o número de telefone para Sam, mas Sam fornece um pedaço de papel com "1123581321" escrito. Você não podia ter certeza se Sam é apenas um fã dos oito primeiros números de Fibonacci ou se é um número de telefone. Para adivinhar, você terá que levar em consideração o contexto e as dicas disponíveis, como talvez você tenha pedido um número de telefone para Sam há um dia atrás ou a nota seja "Ligue para mim" ou se você contar os dígitos e encontrar ele corresponde aos padrões da maioria dos números de telefone. Só então você saberia que é um número de telefone para o qual você pode ligar e não alguns dígitos que você digitaria em uma calculadora.

Observe como essas dicas que levaram você a supor que o número era um número de telefone são semelhantes a como as dicas levam uma linguagem de computador que não requer declaração para deduzir o tipo de um valor.


3
Esta é a resposta mais próxima. Tudo tem a ver com memória. Você declara o tipo para que o compilador saiba quanta memória o aplicativo deve solicitar em tempo de execução. Saber como os bits devem ser interpretados é secundário.
Greg Burghardt

@GregBurghardt true. Para entender os bits já presentes, além de colocá-los em primeiro lugar após a conversão de dados em binários de acordo com o tipo de dados.
Peeyush Kushwaha

10

Em alguns idiomas, você não precisa especificar o tipo de dados.

Os idiomas que suportam a inferência de tipo geralmente podem descobrir o tipo de dados do seu uso. Por exemplo,

var name = "Ali"

é digitado internamente como uma sequência, porque o valor é cercado por aspas.

Alguns idiomas também não exigem que você declare a variável; a variável é criada quando é usada pela primeira vez. No entanto, é considerado uma prática recomendada declarar especificamente suas variáveis ​​por vários motivos importantes; principalmente porque fazê-lo melhor expressa sua intenção.


5
O var name = "Ali"estilo é realmente comum para linguagens modernas de tipo estaticamente . Nas linguagens de tipo estaticamente, o tipo é fixo na criação, mas ainda pode ser determinado pelo inicializador. A definição de uma linguagem digitada dinamicamente é que os tipos se anexam a valores, não a variáveis. Atribuir um valor a uma variável, portanto, define o tipo das variáveis ​​também.
MSalters

@MSalters: fiz um pequeno ajuste na redação.
Robert Harvey

5
A ironia aqui é que isso inclui C # com esta sintaxe exata.
Derek Elkins

1
@MSalters Atribuir um valor a uma variável também define o tipo das variáveis. Ou que a variável não possui um tipo inerente e o intérprete tentará aplicar qualquer operação ao valor da variável. Existem idiomas tipados dinamicamente em que códigos como o seguinte (Javascript) não seriam permitidos var x = 5; x = "";porque a primeira instrução faz xcom que o tipo "Number" seja associado x? Tipo de conflitos com a digitação dinâmica . E se não, qual o efeito do tipo associado à variável, além da associação do tipo ao valor?
Zev Spitz

1
@ ZevSpitz: O primeiro tipo de sistema não é digitado dinamicamente, mas não é digitado. Seu exemplo de Javascript não é digitado dinamicamente, precisamente porque o tipo Number não pode ser alterado. Em um idioma digitado dinamicamente, x = "";altera o tipo de x para string, mesmo que fosse um número anteriormente.
precisa saber é o seguinte

9

Porque é isso que o design da linguagem especifica. Portanto, para responder sua pergunta, precisamos examinar a intenção por trás da digitação explícita em linguagens como C # e C ++. (Bem, o C # faz isso porque o C ++ faz porque o C faz, por isso precisamos examinar a intenção dessa época).

Primeiro, a digitação explícita e estática fornece rigor na codificação - especificar uma variável como um número inteiro significa que o compilador e o software devem ser surpreendidos e gerar um erro ao atribuir um caractere ou sequência à variável. A digitação dinâmica pode causar dores de cabeça para os incautos (basta olhar para a abordagem PHP ou javascripts da veracidade de coisas como matrizes e cadeias vazias).

Você pode ter estática com a digitação implícita - inicializar uma variável como uma string significa que a variável deve ser apenas uma string, mas minha sensação é de que isso pode causar problemas para os humanos que leem o código (eu tendem a assumir a digitação dinâmica quando há uma digitação implícita )

Além disso, é possível, em alguns idiomas, escrever algo como esse pseudocódigo para inicializar uma classe a partir de uma entrada de string:

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

Segundo, a digitação explícita também anda de mãos dadas com a alocação de memória. Um int é sempre tantos bytes. Um número de telefone tem tantos bytes. O compilador pode atribuir um bloco de memória de tamanho apropriado que pode ser usado posteriormente sem precisar ver quanto espaço será necessário quando você atribui um valor.

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

Finalmente, remove a confusão ... 123 é um número inteiro ou um número inteiro não assinado? Eles precisam do mesmo número de bytes, mas o valor máximo armazenado nas variáveis ​​de qualquer tipo é muito diferente ...

Isso não significa que explícito é melhor que implícito - mas o design da linguagem se baseia nesses tipos de opções, e o C # funcionaria de maneira diferente com a digitação implícita. PHP e javascript funcionariam de maneira diferente com a digitação explícita.


5

Porque Sam é mais esperto que os compiladores. Por exemplo, quando você diz que me fornece o número de telefone, não especifica se deseja o prefixo do país ou o código de área, se é o número comercial em que apenas os últimos 4 dígitos são necessários. Além disso, se você pedir o número da junta de pizza local, poderá lidar com a resposta "pizza4u".

Sam, descobre isso a partir do contexto. Enquanto o compilador também pode descobrir isso a partir do contexto, Sam será melhor nisso (e é capaz de interromper o processo para solicitar esclarecimentos).

Existem duas abordagens básicas para tipos e variáveis: a variável tem um tipo; nesse caso, as ações que não são permitidas pelo tipo são proibidas e impedem a compilação, ou o valor tem um tipo e as ações que não são permitidas pelo tipo são capturados em tempo de execução.

Cada abordagem tem suas vantagens e desvantagens. Em geral, os criadores de compiladores tentam minimizar as desvantagens e maximizar as vantagens. É por isso que o C #, por exemplo, permite var phoneNumber = GetPhoneNumber();e deduz o tipo de phoneNumber da assinatura de GetPhoneNumber. Isso significa que você deve declarar o tipo do método, mas não a variável que recebe o resultado. Por outro lado, existem vários tipos de dica / aplicação de projetos para javascript. Tudo é uma troca.


3

É uma questão de como os dados são armazenados. Sua interação com Sam faria uma comparação melhor se você estivesse perguntando para que você pudesse anotá-la, mas tivesse apenas oito caracteres em papel.

"Sam, me dê o número do telefone".

"5555555555"

"Ah, não, estou sem papel. Se ao menos soubesse antecipadamente quantos dados solicitava, poderia ter me preparado melhor!"

Portanto, a maioria dos idiomas faz com que você declare um tipo, para que ele saiba e se prepare com antecedência:

"Sam, quanto tempo é um número de telefone?"

"Dez caracteres."

"Ok, então deixe-me pegar um pedaço maior de papel. Agora me dê o número do telefone".

"5555555555"

"Entendi! Obrigado Sam!"

Fica ainda mais inchado quando você olha para as formas fundamentais reais de armazenamento dos dados. Se você é como eu, tem um caderno com anotações diversas, números apenas rabiscados, sem contexto ou etiqueta para nada, e não tem idéia do que isso significa três dias depois. Este é um problema para computadores muitas vezes também. Muitos idiomas têm tipos "int" (int, long, short, byte) e "float" (float, double). Por que isso é necessário?

Bem, primeiro vamos ver como um número inteiro é armazenado e geralmente representado dentro do computador. Você provavelmente está ciente de que, no nível básico, é tudo binário (1 e 0). Binário é na verdade um sistema numérico que funciona exatamente como o nosso sistema numérico decimal. Em decimal, você conta de 0 a 9 (com zeros iniciais implícitos infinitos que você não escreve), depois reverte para 0 e incrementa o próximo dígito para obter 10. Você repete até rolar de 19 para 20, repita até rolar de 99 para 100 e assim por diante.

Binário não é diferente, exceto que, em vez de 0 a 9, você conta de 0 a 1. 0, 1, 10, 11, 100, 101, 110, 111, 1000. Portanto, quando você digita 9, na memória gravada em binário como 1001. Este é um número real. Pode ser adicionado, subtraído, multiplicado, etc., exatamente dessa forma. 10 + 1 = 11. 10 + 10 = 100 (passe 1 para 0 e carregue o 1). 11 x 10 = 110 (e equivalente 11 + 11 = 110).

Agora, na memória real (registradores incluídos), há uma lista, matriz, como você quiser chamá-lo, de bits (1 ou 0 potencial) próximos um do outro, e é assim que ele mantém esses bits logicamente organizados para criar um número maior que 1. O problema é o que você faz com decimais? Você não pode simplesmente inserir um pedaço de hardware entre os dois bits no registro, e custaria muito adicionar "bits decimais" entre cada par de bits. Então o que fazer?

Você o codifica. Geralmente, a arquitetura da CPU ou do software determinará como isso é feito, mas uma maneira comum é armazenar um sinal (+ ou -, geralmente 1 é negativo) no primeiro bit do registro, uma mantissa (seu número mudou no entanto, muitas vezes é necessário livrar-se do decimal) para o seguinte número X de bits e um expoente (o número de vezes que você precisou alterá-lo) para o restante. É semelhante à notação científica.

Digitar permite que o compilador saiba o que está olhando. Imagine que você tenha armazenado o valor 1.3 no registrador 1. Vamos criar o nosso próprio esquema de codificação sofisticado aqui, 1 bit para sinal, 4 para mantissa, 3 para expoente (1 bit para sinal, 2 para magnitude). Como é um número positivo, o sinal é positivo (0). Nossa mantissa seria 13 (1101) e nosso expoente seria -1 (101 (1 para negativo, 01 = 1)). Então, armazenamos 01101101 no registro 1. Agora, não digitamos essa variável; portanto, quando o tempo de execução vai usá-la, ele diz "claro, este é um número inteiro, por que não", portanto, quando imprime o valor, vemos 109 (64 + 32 + 8 + 4 + 1), o que obviamente não está certo.

Porém, nem todo idioma exige que você digite explicitamente. O C # tem uma palavra-chave "var" que faz com que o tipo de uma variável seja interpretado em tempo de compilação, e outros idiomas como Javascript são totalmente digitados dinamicamente, a ponto de você poder armazenar um número inteiro em uma variável e atribuí-lo a um booleano. atribua-o novamente a uma string e o idioma acompanhará tudo.

Mas é muito mais fácil no compilador, no intérprete ou no tempo de execução - e geralmente resulta em um programa mais rápido, pois ele não precisa gastar recursos valiosos classificando a digitação de tudo - para perguntar ao programador que tipo de dados que você está fornecendo.


2

Existem linguagens de programação nas quais você não precisa declarar tipos de dados para suas variáveis. Existem até linguagens de programação em que você não precisa declarar variáveis ​​com antecedência; você pode usá- los imediatamente.

O problema de não declarar nomes de variáveis ​​é que, se você digitar o nome de uma variável acidentalmente, agora criará acidentalmente uma nova variável completamente não relacionada. Então, quando você executa seu programa, não consegue descobrir por que diabos essa variável que você configurou repentinamente não tem nada ... Até que, depois de muitas horas de depuração, você percebe que digitou o nome errado! GRRR !!

Então eles fizeram isso, então você deve declarar os nomes das variáveis ​​que você usará antes. E agora, quando você digita um nome errado, recebe um erro em tempo de compilação, que informa imediatamente exatamente onde está o erro, antes mesmo de o programa ser executado. Isso não é muito mais fácil?

O mesmo acordo com os tipos de dados. Existem linguagens de programação nas quais você não precisa declarar que tipo de coisa deve ser. Se você tem uma customervariável que na verdade é apenas o nome de um cliente, não o objeto inteiro do cliente, tentar buscar o endereço do cliente a partir de uma sequência comum simples ... não vai funcionar. O ponto principal da digitação estática é que o programa não será compilado; ele reclamará alto, apontando para o local exato onde está o problema. Isso é muito mais rápido do que executar seu código e tentar descobrir por que diabos não está funcionando.

Todos esses são recursos para informar ao compilador o que você pretendia fazer, para que ele possa verificar o que você realmente fez e se certificar de que faz sentido. Isso possibilita ao compilador localizar automaticamente erros para você, o que é um grande problema.

(No passado distante, você não precisava declarar sub-rotinas . Você faria apenas GOSUBcom um número de linha específico. Se desejasse passar informações entre sub-rotinas, definiria variáveis ​​globais específicas, chamaria sua sub-rotina e inspecionaria outras quando a sub-rotina retorna. Mas isso torna assustadoramente fácil inicializar um dos parâmetros. Agora, quase todas as linguagens de programação modernas exigem que você declare quais parâmetros reais uma sub-rotina exige, para que possamos verificar se você especificou todos eles. )


1
Em C ++, você pode colocar "auto x = 1" e ele sabe que é um int. auto y = 1,2; auto z = 'Z'; etc
QuentinUK 21/03

@QuentinUK Em C #, você pode colocar var x=1com resultados semelhantes. Mas isso não é nada; em Haskell, você pode escrever seu programa inteiro sem assinaturas de tipo em tudo, mas tudo é digitado estaticamente, e você ainda receber erros se você cometer um erro ... (Não exatamente convencional embora.)
MathematicalOrchid

@QuentinUK Mas se você escrever, for (auto i=0; i<SomeStdVector.size(); ++i)seu linter irá reclamar porque deduziu um tipo assinado e você o comparará a um tipo não assinado. Você precisa escrever auto i=0ul(colocando as informações de tipo explicitamente novamente, portanto, basta escrever size_t i=0em primeiro lugar).
dmckee

1

Se eu estiver usando o idioma inglês normal, não preciso declarar PhoneNumber como int para usá-lo. Por exemplo, se eu pedir ao meu amigo Sam para me dar seu número de telefone, digo:

"Sam me dê o número do telefone"

Eu não diria>

"Char (20) Sam me dê o int phoneNumber"

Por que precisamos especificar o tipo de dados?

para o MathOverflow ou para a Teoria da Ciência da Computação e leia por um tempo para ter uma idéia de como os humanos se comunicam com alogritmos quando querem garantir que não há possibilidade de mal-entendidos. Ou leia o padrão para alguma linguagem de programação madura.

Você descobrirá que definir que tipos de valores são permitidos para um termo faz parte de uma prática de comunicação realmente precisa, mesmo de humano para humano.

O que você notou é que as interações diárias são razoavelmente regulares e humanas são bastante tolerantes a falhas; portanto, um mal-entendido sobre números de telefone geralmente é evitado pelo conhecimento compartilhado dos participantes.

Mas você já tentou anotar um número de telefone para alguém em outro país? Eles disseram explicitamente quantas vezes você deve pressionar zero para chegar ao endereçamento internacional? Eles disseram o código do país? Você reconheceu isso como tal? Quantos dígitos você esperava? Quantos você conseguiu? Você sabia como agrupar os dígitos? Ou mesmo se o agrupamento tiver significado?

De repente, o problema é muito mais difícil e você provavelmente tomou muito mais cuidado para verificar explicitamente se o número recebido foi entendido da maneira que o remetente queria.


0

Outro motivo para declarar tipos é eficiência. Enquanto um número inteiro pode ser armazenado em 1 byte, 2 bytes ou 4, um programa que usa um número muito grande de variáveis ​​pode usar 4 vezes a memória necessária, dependendo do que está sendo feito. Somente o programador sabe se um espaço de armazenamento menor é viável, para que ele possa dizer isso declarando o tipo.

Além disso, objetos digitados dinamicamente permitem muitos tipos possíveis em tempo real. Isso pode resultar em sobrecarga "oculta", diminuindo a velocidade do programa em comparação com a persistência de um tipo o tempo todo.


0

Várias linguagens de programação anteriores (especialmente o Fortran) não exigiam que você declarasse variáveis ​​antes do uso.

Isso levou a uma série de problemas. Uma realmente óbvia é que o compilador não pode mais capturar erros tipográficos simples com a mesma confiabilidade. Se você possui um código que deveria modificar uma variável existente, mas possui um erro de digitação, ainda possui um código perfeitamente legítimo que acabou de criar (e atribuir um valor a) uma nova variável:

longVariableName = 1

// ...

longVaraibleName = longvariableName + anotherLongVariableName

Agora, analisando isso isoladamente, com o fato de eu já ter mencionado um erro de digitação como a fonte do problema, provavelmente é muito fácil encontrar o erro de digitação e o problema aqui. Em um programa longo, onde isso está oculto no meio de muitos outros códigos, é muito mais fácil perder.

Mesmo atualmente com muitos idiomas de tipo dinâmico, você ainda pode obter o mesmo problema básico com bastante facilidade. Alguns têm alguma facilidade para avisá-lo se você atribuir a uma variável, mas nunca a leem (que heuristicamente detecta alguns problemas como esse), outros não têm essas coisas.


0

Quando você declara qualquer variável, algum espaço é alocado na memória, mas a máquina (neste caso, o computador) ainda não sabe quanto espaço deve ser alocado para essa variável.

Exemplo: - você cria um programa que solicita que o usuário insira qualquer número; nesse caso, é necessário especificar um tipo de dados para armazenar esse número; caso contrário, a máquina não pode julgar por si mesma que deve alocar 2 bytes ou 2 gigabytes , se tentar fazer alocação por si só, isso pode resultar em uso ineficiente de memória. Por outro lado, se você especificar o tipo de dados em seu programa, após a compilação, a máquina alocará o espaço adequado de acordo com a necessidade.


este não parece oferecer nada substancial sobre pontos feitos e explicado em anteriores 11 respostas
mosquito

1
Mosquito, você deve, mais uma vez, ler todas as respostas cuidadosamente e ver que eu tentei responder a essa pergunta de uma maneira muito mais simples que se pode entender facilmente.
precisa saber é o seguinte

Acabei de verificar novamente as três respostas mais recentes postadas cerca de uma hora antes desta e todas as três parecem estar fazendo o mesmo ponto e, de acordo com a minha leitura, explico-o de uma maneira mais simples do que aqui
gnat

Embora eu não tenha respondido pela recompensa do seu voto, mas acho que você deve conhecer uma coisa, você deve recusar uma resposta, pois ela pode fornecer informações inúteis ou erradas e se contém algo ofensivo. Todas as respostas que possuem informações mais úteis e relevantes receberão um número maior de votos suficientes para diferenciar entre uma resposta, uma boa resposta e a melhor resposta. Sua atividade infantil de downvoting uma resposta sem quaisquer razões fortes só vai desencorajar outras pessoas que também querem partilhar a sua opinião que acha que pode ser útil para os outros
Atul170294

1
Provavelmente, sua resposta foi recusada porque não está correta. A digitação estática não é necessária para ajudar no gerenciamento de memória. Existem muitos idiomas que permitem a digitação dinâmica e esses idiomas / ambientes são capazes de lidar com os problemas de gerenciamento de memória mencionados.
Jay Elston 23/03
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.