변수를 선언 할 때 왜 데이터 유형을 지정해야합니까?


41

대부분의 코딩 언어에서 (모두는 아님) 변수를 선언해야합니다. 예를 들어 C #에서 숫자 필드 인 경우

int PhoneNumber

나는 보통 영어를 사용하고 있다면 나는 선언 할 필요가 없습니다 PhoneNumberint사용할 수 있습니다. 예를 들어 친구 Sam에게 전화 번호를달라고 요청하면 다음과 같이 말합니다.

"전화 번호주세요"

나는 말하지 않을 것이다

"Char (20) Sam은 전화 번호를 알려주세요"

왜 데이터 유형을 지정해야합니까?


83
영어가 암시 적으로 타이핑하기 때문입니다. 따라서 귀하PhoneNumber 는 암시 적으로 PhoneNumber 로 타이핑됩니다. 인간도 동적 메모리 할당을 가지고 있습니다 ...;)
HorusKol

28
당신과 샘은 전화 번호가 숫자로 구성되어 있다는 것을 알고 있으며 그 안에있는 문자를 발견하면 놀랄 것입니다. 컴퓨터는 말을 할 필요가 없습니다.
Thorbjørn Ravn Andersen

16
그리고 영화에서 1-800-JIMBO와 같은 숫자를들을 때, 제 생각은 : 어떻게 숫자 입니까? Oo
muru

103
phoneNumber를 int로 선언하면 안됩니다. 대부분의 프로그래밍 언어에서 선행 0을 삭제합니다.
Aron_dc

25
@HorusKol : 인간은 동적 메모리 할당뿐만 아니라 고도로
보수적이지 않은

답변:


79

대부분의 코딩 언어에서 (모두는 아님) 변수를 선언해야합니다.

[…]

왜 데이터 유형을 지정해야합니까?

이것들은 두 가지 독립적 인 질문입니다.

  • 변수를 선언해야하는 이유는 무엇입니까?
  • 왜 타입을 선언해야합니까?

덧붙여 말하면, 우리 둘 다에 대한 답은 아닙니다.

타입을 선언 할 필요가없는 정적 타입의 프로그래밍 언어가 많이 있습니다. 컴파일러는 주변 컨텍스트 및 사용법에서 유형을 유추 할 수 있습니다.

예를 들어 스칼라에서는

val age: Int = 23

아니면 그냥 말할 수 있습니다

val age = 23

이 둘은 정확히 동일합니다. 컴파일러는 형식 Int이 초기화 식에서 온 것으로 유추합니다 23.

마찬가지로 C♯에서도 다음 중 하나를 말할 수 있으며 둘 다 똑같은 것을 의미합니다.

int age = 23;
var age = 23;

이 기능을 타입 추론 이라고하며 , 스칼라와 C♯ 외에 많은 언어가 있습니다 : Haskell, Kotlin, Ceylon, ML, F♯, C ++. Java조차도 형식 유추의 형식이 제한되어 있습니다.

동적으로 유형이 지정된 프로그래밍 언어에서 변수에는 유형이 없습니다. 유형은 런타임시에만 동적으로 존재하며 정적으로는 아닙니다. 값과 표현식에만 유형이 있으며 런타임에만 변수에 유형이 없습니다.

예를 들어 ECMAScript에서 :

const age = 23;
let age = 23;

마지막으로, 많은 언어에서 변수를 선언 할 필요조차 없습니다. 예를 들어 Ruby에서 :

age = 23

실제로 마지막 예제는 여러 프로그래밍 언어에서 유효합니다. 예를 들어 똑같은 코드 줄도 파이썬에서 작동합니다.

그래서,

  • 변수에 유형이있는 정적으로 유형이 지정된 언어 일지라도 반드시 선언 할 필요는 없습니다.
  • 동적으로 유형이 지정된 언어에서 변수에는 유형이 없으므로 분명히 선언 할 수 없습니다 .
  • 많은 언어에서 변수를 선언 할 필요조차 없습니다.

2
타입 추론과 동적 타이핑 (late binding)을 설명하기위한 하나
dcorking

36
이것은 질문 뒤에 오해에 대한 훌륭한 정보이지만 여전히 질문에 답하지 않습니다. 더 적절한 질문은 그것을 필요로하는 언어로 변수 선언 할 때 데이터 유형을 지정 해야합니까? 왜 그렇게 설계 되었습니까? 그 질문에 대한 좋은 대답이 있으며 대안을 정교하게 다루면서 OP의 지평을 넓히고 매우 훌륭합니다.
KRyan

7
@ KRyan : 특정 언어 디자이너가 특정 언어 디자인을 선택한 이유를 알고 싶다면 해당 언어 디자이너에게 물어봐야합니다. C♯의 디자이너가 왜 형식 추론을 결정했는지, 왜 나중에 마음이 바뀌 었는지 말할 수는 없습니다. 언어 디자인은 많은 의견을 가지고 있으며 종종 맛이 나옵니다. OTOH, 당신이 관련된 특정 절충에 대해 알고 싶다면 대답은 기본적으로 스택 교환에 비해 너무 넓은 피어스 교수의 유형 및 프로그래밍 언어 를 다시 인쇄 하는 것입니다.
Jörg W Mittag

2
JörgWMittag : @KRyan이 이미 말했듯이, "필요하지 않다"는 대답은 그리 흥미롭지 않습니다. "유형을 선언하고 싶은 이유"라는 질문은 훨씬 더 흥미롭고 원래 질문의 정신을 더 잘 반영합니다. (답은 "우리가 어디에 있나?" ! " ). 타입 선언에 유리한 이유를 제공하기 위해 특정 언어의 디자이너가 당시에 무엇을 생각했는지 알 필요가 없습니다.
jfs

1
@Zaibis : auto i = 1 // i is inferred to type intvector<int> vec; auto itr = vec.iterator(); // itr is inferred to type vector<int>::iterator. 그것이 정확히 어떻게 작동하는지 알고 싶다면 사양에서 찾아 볼 수 있습니다.
Jörg W Mittag

53

자연어를 사용하여 정보를 언급 할 때, 정보는 매우 정확하지 않으며, 특히 의도에 대해 다른 사람들과 의사 소통하지 않습니다. 자연어로 수학을 할 때 비슷한 문제가 발생합니다. 정확하지는 않습니다.

프로그래밍은 복잡합니다. 오류가 너무 쉽게 발생합니다. 유형은 오류 조건을 감지하여 불법 프로그램 상태를 방지하도록 설계된 검사 시스템의 일부입니다. 언어마다 유형을 다르게 사용합니다. 일부 언어는 유형을 많이 사용하여 컴파일시 오류를 감지합니다. 거의 모든 언어에는 런타임 오류로 호환되지 않는 유형이라는 개념이 있습니다. 일반적으로 유형 오류는 프로그램에서 일종의 버그를 나타냅니다. 오류가 발생하더라도 프로그램을 계속 사용할 수있게되면 매우 나쁜 답변을 얻을 수 있습니다. 우리는 잘못되거나 틀린 답을 얻기보다는 프로그램을 중단하는 것을 선호합니다.

달리 말하면, 타입은 프로그램의 동작에 제약을 나타냅니다. 일부 메커니즘에 의해 강제 될 때 제약 조건이 보장됩니다. 이러한 보장은 프로그램에 대해 생각하는 데 필요한 추론의 양을 제한하여 프로그래머를 위해 프로그램을 읽고 유지 관리하는 작업을 단순화합니다. 형식 오류와 형식 오류를 감지하는 도구 (예 : 컴파일러)에 대한 의미가 없으면 프로그래밍 부담이 상당히 높아져 비용이 더 많이 듭니다.

(많은) 인간이 유럽, 미국 및 국제 전화 번호를 쉽게 구분한다는 것은 사실입니다. 그러나 컴퓨터는 실제로 "생각"하지 않으며, 말하면 유럽에서 미국 전화 번호로 전화를 걸거나 그 반대로 할 것입니다. 예를 들어, 유형은 컴퓨터에 "생각"하는 방법을 가르치지 않고도 이러한 경우를 구별하는 좋은 방법입니다. 일부 언어에서는 미국 전화 시스템에서 유럽 전화 번호를 혼합하려고하면 컴파일 시간 오류가 발생할 수 있습니다. 이 오류는 프로그램을 실행하기 전에 프로그램을 수정해야 할 수도 있습니다 (전화 번호를 국제 전화 걸기 순서로 변환하거나 유럽의 전화 번호를 대신 사용하여).

또한 컴퓨터가 생각하지 않기 때문에 필드 또는 변수의 이름 (예 phonenumber:)은 컴퓨터에 아무 의미가 없습니다. 컴퓨터에서 해당 필드 / 변수 이름은 "blah123"입니다. 모든 변수가 "blahxxx"인 경우 프로그램이 어떻게 작동하는지 생각해보십시오. Yikes. 그게 컴퓨터가 보는 것입니다. 유형을 제공하면 컴퓨터는 단순히 이름만으로는 추론 할 수없는 변수의 의미에 잉크를 공급합니다.

또한 @Robert가 말했듯이 많은 현대 언어에서는 C #과 같은 언어가 "유형 추론"을 수행하므로 이전에했던 것처럼 유형을 지정하지 않아도됩니다.이 유형은 적절한 유형을 결정하는 규칙 세트입니다. 상황에 맞는 변수. C #은 로컬 변수에 대한 형식 유추 만 제공하지만 공식 매개 변수 또는 클래스 또는 인스턴스 필드에는 제공하지 않습니다.


4
슬픈 부분은 RE : 공개 액세스 가능한 멤버 (공용 필드, 공개 메소드 서명)의 유형을 추론하는 것은 불가능합니다. 언제 어떻게 사용 될지 예측할 수 없기 때문입니다. 또한 타입 주석은 문서입니다.
Sergio Tulentsev 2016 년

이 행을 강조 표시하거나 굵게 표시해야한다고 생각합니다 . .. Types are part of a system of checks that ...OP에 직접 응답하기 때문에 Why do we have to specify data type at all?..
txtechhelp

참고 : 대답은 유형을 지정하는 데 사용되는 언어가 일반적인 프로그래밍 언어보다 오류를 피하는 데 더 낫다고 가정합니다. 예를 들어 Turing-complete 인 C ++ 템플릿 언어를 고려하면 (따라서 많은 오류 검사를 표현할 수 있음) Haskell, Python 및 C ++ 자체. 같은 프로그램 언어를 사용하여 프로그램의 나머지 부분과 같은 오류 검사를 표현하지 않는 이유를 스스로에게 물어보십시오 (일부 경우에는 좋은 답변이 있습니다).
jfs

@SergioTulentsev 사실이 아닙니다. F #에서는 형식을 명시 적으로 지정하지 않고도 공용 메서드를 사용할 수 있습니다. 컴파일러는 메소드 내부의 사용법에서 유형을 유추합니다. 예를 들어, 유효한 공용 메소드 정의는 다음과 같습니다. static member add x y = x + y, member x.Append s = x.Text + s. 첫 번째 경우 xy것으로 추정한다 int때문에 첨가 S. 두 번째 경우에는 유형에 따라 유효한 것입니다. x.Texta string인 경우에도 유효 합니다. 그래도 형식 주석이 문서임을 동의합니다. sstring
Roujo

"암시 적 로컬 유형, 명시 적 인터페이스 유형"은 Haskell과 같은 언어에서도 컴파일러가 엄격한 유형을 유추하면서도 거의 모든 유형을 생략 할 수 있는 많은 사람들이 프로그래밍하는 방식입니다. 언어가이 방법을 강요 할 때 슬프다 고 생각하지 않는 사람들이 많이 있습니다 (C #처럼).
Ben

29

다른 답변 외에도 포함해야 할 것이 하나 있습니다. 컴퓨터는 단지 비트입니다. 내가 당신에게 바이트를 준다고 가정 해보십시오.

26 3A 00 FF

그게 무슨 이야? 그것은 컴퓨터에 의해 이런 식으로 저장되지만 해석이 없으면 비트 입니다. 4 개의 ASCII 문자 일 수 있습니다. 정수일 수 있습니다. 배열의 일부 바이트 일 수 있습니다. 개체의 일부일 수 있습니다. 그것은 고양이 비디오가 버퍼링되는 위치에 대한 포인터 일 수 있습니다. 거의까지 필요에에 어셈블리에서 모든 프로그래밍 언어 뭔가 그들에게 의미있는 계산을 할 수 있도록하기 위해 비트를 해석하는 방법을 알고 있습니다.

그리고 컴퓨터는 이러한 비트의 의미를 알 수 없으므로 명시 적으로 형식 주석을 통해 또는 다른 답변에서 언급 된 형식 유추 메커니즘을 통해 알려야합니다.


10
하지만 정말에 충실 충분히 당신의 마음, 컴퓨터가 없다는 것을 실현 머뭇 거리는 결코 할 수 이해 하는 비트가 당신이 그것을 말해 많은 종류의 주석에도 의미가 무엇인지를. 여러분의 설명은 첫 16 진수를 "명확하게"하기 위해 더 많은 16 진수로 바뀌게됩니다. 의의는 전자 제품에 의도를 넣고 우리가 의도 한대로하게하기 위해 사람들에 의해 만들어졌습니다. 이제 엔지니어에게 "감사합니다"라고 말합니다. :)
와일드 카드

1
메인 프레임에서 프로그래밍하는 데 몇 년을 보냈습니다. PL / 1을 사용하면이 대답은 많은 의미가 있습니다. 꽤 정기적으로 우리는 다른 방식으로 바이트에 액세스하기 위해 다른 데이터 유형의 다른 변수의 주소로 설정된 포인터를 기반으로 스토리지 기반을 사용합니다. 예를 들어 PL / 1은 1 바이트 이진 숫자 필드를 지원하지 않지만 6 개의 단일 바이트 이진 필드를 저장하는 6 바이트 배열을 저장할 수 있도록 주소에 1 개의 문자 변수를 사용합니다 (이 경우 저장 가능) 주소 당 6 바이트-스토리지가 비쌀 때 중요합니다.
킥 스타트

1
컴퓨터는 많은 가능성을 이해할 수 있지만 영리한 컴파일러조차도 이해해야 할 상황이 필요합니다. 숫자 0 또는 "0"과 동일하지 않습니다. 또는 문자열 "Dec 31"은 "5 월 1 일"이 문자열로 처리되기 전에 주문되지만 날짜로 취급되는 경우에는 주문되지 않습니다. 또는 5/2를 가져 가라. 엔터는 2, 더블은 2.5입니다. 또한이 유형은 원치 않는 변환에 대한 보안 수단입니다. Null, NaN 및 반올림 또는 오버플로도 문제가 될 수 있습니다. 강력하고 정적으로 유형이 지정된 언어에는 몇 가지 장점이 있습니다. 예를 들어, 컴파일러는 리팩토링 중에 문제점을 발견하도록 도와줍니다.
Borjab

1
@Borjab "2는 정수 "라는 의미입니까?
Richard Everett

1
@RichardEverett 확실히 그것은 랩 소스였습니다. 고마워하지만 늦게 편집했습니다.
Borjab

23

컴퓨터가이 정보를 필요로 하는 이유에 대한 답 은 데이터 표현 과 관련이 있습니다.

"데이터 유형"의 이름은 컴퓨터 메모리에있는 원시 상태 0과 1에서 정보를 컴퓨터가 저장하고 검색하는 데 도움이되는 규칙에 대한 참조입니다.

예를 들어, 일반 8 비트 ASCII 문자는 컴퓨터 메모리 (RAM 또는 디스크)에 01000001(대문자 "A", ASCII 코드 65) 또는 00001000(백분율 부호) 또는 0과 8 비트에서 1입니다.

다른 예에서, 일부 8 비트 부호없는 정수는 00000101(숫자 5) 또는 00001000(숫자 8) 로 저장 될 수있다

8과 % 문자의 이진 표현은 어떻게 동일 할 수 있지만 유형이 다르기 때문에 다른 의미를 갖습니다.

데이터 유형을 유추하는 언어라도 "모든 변수 유형은 프로그래머가 선언해야합니다"라는 규칙이 없을 수 있으며 "일련의 문자가 따옴표로 묶인 경우 문자열"과 같은 규칙이 있습니다. 각 데이터 유형에 대한 더 많은 규칙.

따라서 0과 1의 의미를 이해하기 위해 데이터 유형이 필요하기 때문에 예를 들어 두 문자를 "추가"하려는 경우 문자열 연결 기능을 수행하거나 두 개의 정수를 추가하려는 경우 정수 추가를 수행 할 수 있습니다 .

에서 당신의 이야기 도하자 당신이 전화 번호 샘을 요구하지 않았다라고하지만 샘은 당신에게 "1,123,581,321"는에 쓰여진이 종이를 제공합니다. Sam이 처음 8 개의 피보나치 수의 팬인지 또는 전화 번호인지는 확실하지 않습니다. 추측하기 위해서는 하루 전에 Sam에게 전화 번호를 요청했거나 메모에 "Call Me"라고 말했거나 숫자를 세어 찾은 경우 사용 가능한 컨텍스트와 신호를 고려해야합니다. 대부분의 전화 번호 패턴과 일치합니다. 그래야만 전화를 걸 수있는 전화 번호이며 계산기에 입력 한 숫자가 아니라는 것을 알게됩니다.

이 힌트가 전화 번호라는 추측으로 이어진 힌트는 힌트가 값의 유형을 추론하기 위해 선언이 필요없는 컴퓨터 언어를 이끌어내는 방법과 비슷합니다.


3
이것이 가장 가까운 대답입니다. 그것은 모두 메모리와 관련이 있습니다. 컴파일러가 런타임에 요청해야하는 메모리 양을 알 수 있도록 유형을 선언합니다. 비트 해석 방법을 아는 것은 부차적입니다.
Greg Burghardt

@GregBurghardt true. 데이터 유형에 따라 주어진 데이터를 이진으로 변환 한 후 비트를 먼저 인식 할뿐만 아니라 이미 존재하는 비트를 이해합니다.
Peeyush Kushwaha

10

일부 언어에서는 데이터 유형을 지정할 필요가 없습니다.

형식 유추를 지원하는 언어는 일반적으로 사용 현황에서 데이터 형식을 알아낼 수 있습니다. 예를 들어

var name = "Ali"

값은 따옴표로 묶기 때문에 내부적으로 문자열로 입력됩니다.

일부 언어에서는 변수를 선언하지 않아도됩니다. 변수는 처음 사용될 때 만들어집니다. 그러나 여러 가지 중요한 이유로 변수를 구체적으로 선언하는 것이 가장 좋습니다. 주로 그렇게하는 것이 당신의 의도를 더 잘 표현하기 때문입니다.


5
var name = "Ali"스타일은 사실 현대적 으로 정적으로 입력 된 언어에 일반적입니다 . 정적으로 유형이 지정된 언어에서는 유형이 작성시 고정되어 있지만 이니셜 라이저에 의해 여전히 판별 될 수 있습니다. 동적으로 유형이 지정된 언어의 정의는 유형이 변수가 아니라 값에 연결된다는 것입니다. 따라서 변수에 값을 할당하면 변수 유형도 설정됩니다.
MSalters

@MSalters : 나는 문구를 약간 조정했습니다.
Robert Harvey

5
아이러니 한 것은 여기에 정확한 구문을 가진 C #이 포함되어 있다는 것입니다.
Derek Elkins

1
@MSalters 변수에 값을 할당하면 변수 유형도 설정됩니다. 또는 변수에 고유 유형이 없으며 인터프리터는 변수 값에 조작을 적용하려고 시도합니다. var x = 5; x = "";첫 번째 명령문으로 인해 x"번호"유형이 연관되어 있기 때문에 다음과 같은 코드 (Javascript)가 허용되지 않는 동적 유형의 언어 가 x있습니까? 과의 충돌의 정렬 동적 입력 . 그렇지 않은 경우 변수와 연관된 유형이 값과의 유형 연관을 넘어서는 영향은 무엇입니까?
Zev Spitz

1
@ZevSpitz : 첫 번째 종류의 시스템은 동적으로 입력되지 않지만 전혀 입력되지 않습니다. 숫자 유형을 변경할 수 없으므로 Javascript 예제가 동적으로 입력되지 않습니다. 동적으로 유형이 지정된 언어에서는 x x = "";유형 이 이전의 숫자 인 경우에도 문자열로 변경합니다 .
MSalters

9

그것이 언어 디자인이 지정하는 것이기 때문입니다. 따라서 귀하의 질문에 대답하려면 C # 및 C ++와 같은 언어로 명시 적으로 타이핑하는 의도를 살펴 봐야합니다. (음, C #은 C ++이 그렇게하기 때문에 C ++이 그렇게하기 때문에 그렇게하므로 의도적 인 방식을 다시 살펴 봐야합니다).

첫째, 명시 적 및 정적 타이핑은 코딩에서 엄격함을 제공합니다. 변수를 정수로 지정하면 변수에 문자 나 문자열을 할당 할 때 컴파일러와 소프트웨어에 놀라고 오류가 발생해야합니다. 동적 타이핑은 경고에 두통을 일으킬 수 있습니다 (단순히 배열이나 빈 문자열과 같은 것들의 진실성에 대한 PHP 또는 자바 스크립트 접근 방식을 살펴보십시오).

암시 적 타이핑으로 정적을 가질 수 있습니다-변수를 문자열로 초기화한다는 것은 변수가 단지 문자열이어야 함을 의미하지만, 이것이 인간이 코드를 읽는 데 문제를 일으킬 수 있다는 느낌입니다 (암시 적 타이핑이있을 때 동적 타이핑을 가정하는 경향이 있습니다) ).

또한 일부 언어에서는 문자열 입력에서 클래스를 초기화하기 위해이 유사 코드와 같은 것을 작성할 수 있습니다.

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

둘째, 명시 적 타이핑은 메모리 할당과도 관련이 있습니다. INT는 항상 많은 바이트입니다. PHONENUMBER는 많은 바이트입니다. 컴파일러는 적절한 크기의 메모리 블록을 할당 한 후 값을 할당 할 때 필요한 공간을 확인할 필요없이 나중에 사용할 수 있습니다.

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

마지막으로 혼란을 제거합니다 ... 123은 정수 또는 부호없는 정수입니까? 그들은 같은 바이트 수를 필요로하지만 두 유형의 변수에 저장된 최대 값은 매우 다릅니다 ...

이것은 명시 적이 암시 적보다 낫다고 말하지는 않지만 언어 디자인은 이러한 종류의 선택에 의존하며 C #은 암시 적 타이핑과 다르게 작동합니다. PHP와 자바 스크립트는 명시적인 타이핑에서 다르게 작동합니다.


5

Sam은 컴파일러보다 똑똑하기 때문입니다. 예를 들어, 전화 번호를 말하면 마지막 4 자리 만 필요한 작업 번호인지 국가 접두어 또는 지역 번호를 원하는지 여부를 지정하지 않습니다. 또한, 당신은 로컬 피자 조인트의 수를 요청하면, 당신은 대답 "pizza4u"를 다룰 수 있습니다.

샘, 문맥에서 알아 냈어 컴파일러는 맥락에서 그것을 알아낼 수 있지만 Sam은 더 잘 이해할 것입니다 (그리고 프로세스를 중단시켜 설명을 요구할 수 있습니다).

유형과 변수에 대한 두 가지 기본 접근 방식이 있습니다. 변수에는 유형이 있습니다.이 경우 유형에 의해 허용되지 않는 동작은 금지되고 컴파일을 방지하거나 값에 유형과 동작이 허용되지 않습니다. 런타임에 유형이 발견됩니다.

각 접근법에는 장단점이 있습니다. 일반적으로 컴파일러 작성자는 단점을 최소화하고 장점을 최대화하려고합니다. 예를 들어 C # var phoneNumber = GetPhoneNumber();은 getPhoneNumber의 서명에서 phoneNumber의 유형을 허용 하고 추론하는 이유입니다. 즉, 메소드의 유형을 선언해야하지만 결과를받는 변수는 선언하지 않아야합니다. 반면에 자바 스크립트에 대한 다양한 유형의 힌트 / 강화 프로젝트가 있습니다. 모든 것이 절충입니다.


3

데이터가 저장되는 방식에 달려 있습니다. 샘과의 상호 작용은 당신이 그것을 적을 수는 있지만 8 자 정도의 종이 만 가지고 있으면 더 잘 비교할 것입니다.

"샘, 전화 번호를 알려줘."

"5555555555"

"아뇨, 저는 종이가 부족합니다. 내가 요청한 데이터의 양을 미리 알고 있었다면 더 잘 준비 할 수있었습니다!"

대신 대부분의 언어는 유형을 선언하므로 미리 알고 미리 준비합니다.

"전화 번호는 얼마나 되나요?"

"10 자."

"좋아, 그럼 더 큰 종이를 가져 오자. 이제 전화 번호를 알려줘."

"5555555555"

"알았어! 고마워 샘!"

데이터가 저장되는 실제 기본 방법을 살펴보면 훨씬 더 유연 해집니다. 당신이 저와 같다면, 당신은 잡다한 노트, 숫자 만 적어 놓은 것, 상황에 대한 내용이나 라벨링이없는 노트북을 가지고 있고, 3 일 후에 그 의미가 무엇인지 전혀 알지 못합니다. 이것은 컴퓨터에서도 많은 문제입니다. 많은 언어에는 "int"유형 (int, long, short, byte) 및 "float"(float, double) 유형이 있습니다. 왜 필요한가요?

먼저 정수가 어떻게 저장되고 일반적으로 컴퓨터 내에서 표현되는지 살펴 보겠습니다. 기본 수준에서는 모두 이진 (1과 0)이라는 것을 알고있을 것입니다. 이진수는 실제로 우리의 십진수 시스템과 똑같이 작동하는 숫자 시스템입니다. 10 진수로 0에서 9까지 계산하고 (제한하지 않는 무한한 0을 포함) 0으로 롤오버하고 다음 숫자를 증가시켜 10을 갖습니다. 19에서 20까지 롤오버 할 때까지 반복합니다. 99에서 100 등으로 롤오버 될 때까지 반복하십시오.

이진수는 0에서 9가 아니라 0에서 1까지로 계산된다는 점을 제외하면 다르지 않습니다. 0, 1, 10, 11, 100, 101, 110, 111, 1000으로 계산됩니다. 따라서 9를 입력하면 이진수로 기록 된 메모리에 1001입니다. 이것은 실제 숫자입니다. 정확히 그 형태로 더하기, 빼기, 곱하기 등을 할 수 있습니다. 10 + 1 = 11. 10 + 10 = 100 (1을 0으로 롤오버하고 1을 수행). 11 x 10 = 110 (및 동일하게 11 + 11 = 110).

이제 실제 메모리 (레지스터 포함)에는 서로 바로 옆에있는 비트 (잠재적 1 또는 0 ')의 목록, 배열이 있습니다.이 비트를 논리적으로 구성하여 1보다 큰 수입니다. 문제는 소수점 이하 자릿수로 무엇을합니까? 레지스터의 두 비트 사이에 하드웨어를 삽입 할 수 없으며 각 비트 쌍 사이에 "소수 비트"를 추가하는 데 너무 많은 비용이 듭니다. 그래서 뭐 할까?

당신은 그것을 인코딩합니다. 일반적으로 CPU 또는 소프트웨어의 아키텍처는이 작업을 수행하는 방법을 결정하지만 가장 일반적인 방법은 레지스터의 첫 번째 비트에 가수 (숫자가 이동 한 부호) (+ 또는-, 일반적으로 1은 음수)를 저장하는 것입니다. 그러나 여러 번 다음 X 비트 수에 대해서는 소수점을 제거해야하고 나머지는 지수 (이동 해야하는 횟수)입니다. 과학적 표기법과 비슷합니다.

입력하면 컴파일러가보고있는 내용을 알 수 있습니다. 값 1.3을 레지스터 1에 저장했다고 가정 해 봅시다. 여기에는 부호 1 비트, 가수 4, 지수 3 (기호 1 비트, 크기 2)와 같은 멋진 인코딩 방식이 있습니다. 양수이므로 부호가 양수 (0)입니다. 우리 가수는 13 (1101)이고 지수는 -1 (101 (음수의 경우 1, 01 = 1))입니다. 따라서 01101101을 레지스터 1에 저장합니다. 이제이 변수를 입력하지 않았으므로 런타임에서이 변수를 사용하면 "이것은 정수입니다. 왜 그렇지 않습니다"라고 표시되므로 값을 인쇄 할 때 109 (64 + 32 + 8 + 4 + 1), 그렇습니다.

그러나 모든 언어에서 명시 적으로 입력해야하는 것은 아닙니다. C #에는 컴파일시 변수 유형을 해석하는 키워드 "var"이 있으며 Javascript와 같은 다른 언어는 변수에 정수를 저장 한 다음 부울에 할당 할 수있을 정도로 완전히 동적으로 유형이 지정됩니다. 문자열에 다시 할당하면 언어가 모든 것을 추적합니다.

그러나 컴파일러, 인터프리터 또는 런타임에서 훨씬 더 쉽습니다. 프로그래머에게 어떤 종류의 정보를 요청하기 위해 모든 것을 입력하여 정렬하는 데 귀중한 리소스를 소비 할 필요가 없기 때문에 프로그램 속도가 더 빠릅니다. 당신이주는 데이터.


2

변수에 대한 데이터 유형을 선언 할 필요가없는 프로그래밍 언어가 있습니다 . 변수를 미리 선언 할 필요가없는 프로그래밍 언어도 있습니다. 바로 사용할 수 있습니다 .

변수 이름을 선언하지 않는 문제는 실수로 변수 이름의 철자가 틀리면 실수로 완전히 관련이없는 새 변수를 만든 것입니다. 당신이 당신의 프로그램을 실행할 때 왜 그래서, 당신은 알아낼 수 없습니다 도대체 갑자기 설정 변수 즉, 거기에 아무 상관이없는, 디버깅의 몇 시간 후, 당신이 저주 이름을 잘못 입력 실현까지 ...! GRRR !!

그래서 그들은 그것을 만들었으므로 미리 사용할 변수 이름 을 선언 해야합니다. 이제 이름을 잘못 입력하면 컴파일 타임 오류가 발생 하여 프로그램이 실행되기 전에 버그가 어디에 있는지 정확하게 알려줍니다 . 그렇게 쉽지 않습니까?

데이터 형식도 마찬가지입니다. 어떤 유형의 물건을 선언 할 필요가없는 프로그래밍 언어 가 있습니다. customer실제로 전체 고객 객체가 아닌 고객의 이름 인 변수 가있는 경우 일반 일반 문자열에서 고객 주소를 가져 오려고하면 작동하지 않습니다. 전체 지점 정적 형식의 프로그램이 컴파일되지 것입니다; 문제가있는 정확한 장소를 가리키면서 큰 소리로 불평합니다. 그건 훨씬 더 빠르게 코드를 실행하고 지옥이 작동하지 않는 이유를 파악하는 것보다.

이러한 모든 기능은 컴파일러 에게 수행 하려는 작업 을 알려주는 기능 이므로 실제로 수행 한 작업을 확인하고 의미가 있는지 확인할 수 있습니다 . 그러면 컴파일러가 자동으로 버그를 찾을 수 있습니다. 이는 큰 문제입니다.

(먼 과거로 돌아가서, 당신은 서브 루틴 을 선언 할 필요가 없었습니다 . 당신은 단지 GOSUB특정 라인 번호로 전달할 것입니다. 서브 루틴 사이에 정보를 전달하려면, 특정 전역 변수를 설정하고 서브 루틴을 호출 한 후 다른 것을 검사하십시오 변수 중 하나를 초기화하는 것을 잊어 버리기가 매우 쉬워 지므로 이제는 거의 모든 현대 프로그래밍 언어에서 서브 루틴이 취하는 실제 매개 변수를 선언해야하므로 모두 지정했는지 확인할 수 있습니다. )


1
C ++에서는 "auto x = 1"을 입력 할 수 있으며 이것이 int라는 것을 알고 있습니다. 자동 y = 1.2; 자동 z = 'Z'; 기타
QuentinUK

@QuentinUK C #에서는 var x=1비슷한 결과를 넣을 수 있습니다 . 그러나 그것은 아무것도 아닙니다. Haskell에서는 타입 시그니처를 전혀 사용하지 않고 전체 프로그램을 작성할 수 있지만, 정적으로 타이핑되어 있지만 실수를해도 여전히 오류가 발생합니다 ... (정확히 주류는 아닙니다.)
MathematicalOrchid

@QuentinUK 그러나 당신이 작성하는 경우 for (auto i=0; i<SomeStdVector.size(); ++i)linter는 부호있는 유형을 추론하고 그것을 부호없는 유형과 비교 하기 때문에 불평을 할 것 입니다. 당신은 쓰기에있는 auto i=0ul(그래서 그냥 작성해야 명시 적으로 다시에서 형식 정보를 넣어 size_t i=0처음부터).
dmckee

1

일반 영어를 사용하는 경우 PhoneNumber를 int로 선언하여 사용할 필요는 없습니다. 예를 들어 친구 Sam에게 전화 번호를달라고 요청하면 다음과 같이 말합니다.

"전화 번호주세요"

나는 말하지 않을 것이다>

"Char (20) Sam은 전화 번호를 알려주세요"

왜 데이터 유형을 지정해야합니까?

까지 팝 MathOverflow 또는 이론 컴퓨터 과학 및 그들이 오해의 가능성이 없다는 것을 보장하고자 할 때 인간이 서로 alogrithms을 전달하는 방법에 대한 아이디어를 얻을 잠시 동안 읽었다. 또는 일부 성숙한 프로그래밍 언어의 표준을 읽으십시오.

당신은 값의 종류 용어에 허용되는 정의하는 것을 찾을 수 있다 정말 정확한 통신의 일부는 심지어 인간에 인간 연습.

당신이 주목 한 것은 일상적인 상호 작용은 상당히 규칙적이고 인간은 내결함성이 있으므로 전화 번호에 대한 오해는 일반적으로 참가자의 공유 된 지식에 의해 방지됩니다.

그러나 다른 나라의 누군가를 위해 전화 번호를 쓰려고 시도한 적이 있습니까? 국제 주소 지정에 도달하기 위해 제로를 몇 번이나 밀어야하는지 명시 적으로 말했습니까? 그들은 당신에게 그들의 국가 코드를 말했습니까? 그렇게 인식 했습니까? 몇 자리 숫자를 기대 했습니까? 당신은 몇 개를 얻었습니까? 숫자를 그룹화하는 방법을 알고 있습니까? 심지어 경우 그룹화는 의미가있다?

갑자기 문제가 훨씬 더 어려워졌으며 수신 한 번호가 발신자가 의미 한 바를 이해했는지 명시 적으로 확인하기 위해 더 많은주의를 기울 였을 것입니다.


0

유형을 선언하는 또 다른 이유는 효율성입니다. 정수는 1 바이트 또는 2 바이트 또는 4로 저장 될 수 있지만, 많은 수의 변수를 사용하는 프로그램은 수행중인 작업에 따라 필요한 메모리의 4 배를 사용할 수 있습니다. 더 작은 저장 공간이 가능한지 프로그래머 만 알고 있으므로 유형을 선언하여 말할 수 있습니다.

또한 동적으로 유형이 지정된 객체를 사용하면 가능한 많은 유형을 즉시 사용할 수 있습니다. 이로 인해 "후드"아래에 약간의 오버 헤드가 발생하여 한 가지 유형을 고집하는 것에 비해 프로그램 속도가 느려질 수 있습니다.


0

많은 초기 프로그래밍 언어 (특히 Fortran)에서는 사용하기 전에 변수를 선언 할 필요가 없었습니다.

이로 인해 많은 문제가 발생했습니다. 정말 명백한 점 중 하나는 컴파일러가 더 이상 간단한 인쇄상의 오류를 거의 확실하게 잡을 수 없다는 것입니다. 기존 변수를 수정해야하지만 오타가있는 코드가있는 경우 새 변수를 생성하고 값을 할당 한 합법적 인 코드가 여전히 있습니다.

longVariableName = 1

// ...

longVaraibleName = longvariableName + anotherLongVariableName

이제 문제의 원인으로 이미 오타를 언급 했으므로이 문제를 개별적으로 살펴보면 여기에서 오타와 문제를 쉽게 찾을 수 있습니다. 이 코드가 다른 많은 코드의 중간에 묻혀있는 긴 프로그램에서는 놓치기가 훨씬 쉽습니다.

현재 많은 동적 유형의 언어를 사용하더라도 동일한 기본 문제를 여전히 쉽게 얻을 수 있습니다. 일부는 변수에 할당하면 경고 할 기능이 있지만 결코 읽지 마십시오 (이와 같은 몇 가지 문제를 발견하게됩니다).


0

변수를 선언하면 메모리에 일부 공간이 할당되지만 기계 (이 경우 컴퓨터)는 해당 변수에 대해 얼마나 많은 공간이 할당되어 있는지 알지 못합니다.

예 :-사용자에게 숫자를 입력하도록 요청하는 프로그램을 만듭니다.이 경우 해당 숫자를 저장하기 위해 데이터 유형을 지정해야합니다. 그렇지 않으면 기계 가 시도하면 2 바이트 또는 2 기가 바이트를 할당해야한다고 스스로 판단 할 수 없습니다 자체적으로 할당을 수행하면 메모리 사용이 비효율적 일 수 있습니다. 반면에, 프로그램에서 데이터 유형을 지정하면 컴파일 후 머신이 필요에 따라 적절한 공간을 할당합니다.


이것은 이전의 11 가지 답변에서 언급되고 설명 된 포인트를 넘어서는 실질적인 내용을 제공하지 않는 것 같습니다
gnat

1
Gnat 당신은 다시 한 번 모든 대답을 철저히 읽고 내가 쉽게 이해할 수있는 훨씬 간단한 방식 으로이 질문에 대답하려고 노력한 것을보아야합니다.
Atul170294

방금이 질문에 대해 1 시간 전에 게시 된 가장 최근의 답변 3 개를 다시 확인했으며 세 개 모두 동일한 내용을 제시하는 것으로 보이며 내 독서에 따라 여기보다 더 간단한 방식으로 설명합니다
gnat

귀하의 투표 에 대한 보상 에 대해서는 응답하지 않았지만 한 가지 사실을 알아야한다고 생각하지만, 쓸모 없거나 잘못된 정보를 제공 할 수 있고 불쾌한 정보가 포함되어있는 경우 답변을 줄여야합니다. 가장 유용하고 관련성 높은 정보를 가진 모든 답변은 답변, 좋은 답변 및 최상의 답변을 구별하기에 충분한 많은 투표 수를 얻게됩니다. 강력한 이유없이 답을 내리는 당신의 유치한 활동은 다른 사람들에게도 유용하다고 생각되는 의견을 나누고 자하는 다른 사람들을 실망시키지 않을 것입니다.
Atul170294

1
귀하의 답변은 정확하지 않기 때문에 다운 보트되었을 가능성이 높습니다. 메모리 관리를 돕기 위해 정적 타이핑이 필요하지 않습니다. 동적 입력을 허용하는 언어가 많이 있으며 해당 언어 / 환경에서 언급 한 메모리 관리 문제를 처리 할 수 ​​있습니다.
Jay Elston
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.