Wikipedia 를 인용하려면 :
많은 종류의 암시 적 변환을 지원하는 일반적으로 사용되는 두 가지 언어는 C와 C ++이며, 종종 약한 유형의 언어라고 주장됩니다. 그러나 다른 사람들은 이러한 언어가 서로 다른 유형의 피연산자가 혼합 될 수있는 방법에 대해 충분한 제한을두고 있으며 두 가지가 강력한 유형의 언어로 간주되어야한다고 주장합니다.
더 확실한 답이 있습니까?
Wikipedia 를 인용하려면 :
많은 종류의 암시 적 변환을 지원하는 일반적으로 사용되는 두 가지 언어는 C와 C ++이며, 종종 약한 유형의 언어라고 주장됩니다. 그러나 다른 사람들은 이러한 언어가 서로 다른 유형의 피연산자가 혼합 될 수있는 방법에 대해 충분한 제한을두고 있으며 두 가지가 강력한 유형의 언어로 간주되어야한다고 주장합니다.
더 확실한 답이 있습니까?
답변:
"강하게 입력"및 "약하게 입력"은 널리 동의 된 기술적 의미가없는 용어입니다. 의미가 잘 정의 된 용어는 다음과 같습니다.
동적 유형 은 유형이 런타임에 값에 첨부됨을 의미하며 다른 유형의 값을 혼합하려고하면 "런타임 유형 오류"가 발생할 수 있습니다. 예를 들어 Scheme에서 (+ 1 #t)
이것을 작성하여 true에 추가하려고 하면 오류가 발생합니다. 문제가되는 코드를 실행하려는 경우에만 오류가 발생합니다.
정적으로 형식화 됨은 컴파일 시간에 형식이 확인되고 정적 형식이없는 프로그램은 컴파일러에서 거부됨을 의미합니다. 예를 들어, ML에서를 작성하여 true에 1을 추가하려고 1 + true
하면 프로그램이 (아마도 비밀스러운) 오류 메시지와 함께 거부됩니다. 코드가 실행되지 않더라도 항상 오류가 발생합니다.
유연성을 중시하는 정도와 런타임 오류에 대해 걱정하는 정도에 따라 사람마다 다른 시스템을 선호합니다.
때때로 "강력한 유형"은 "정적 유형"을 의미하기 위해 느슨하게 사용되며 "약한 유형"은 "동적 유형"을 의미하는 것으로 잘못 사용됩니다. "강하게 입력 된"이라는 용어의 더 나은 사용은 "유형 시스템을 우회하거나 전복시킬 수 없습니다"라는 것입니다. 반면 "약하게 입력 된"은 "유형 시스템에 허점이 있음"을 의미합니다. 역으로 정적 유형 시스템을 사용하는 대부분의 언어에는 허점이있는 반면 동적 유형 시스템을 사용하는 많은 언어에는 허점이 없습니다.
이러한 용어 중 어느 것도 언어에서 사용할 수있는 암시 적 변환의 수와 어떤 식 으로든 연결되어 있지 않습니다.
프로그래밍 언어에 대해 정확하게 이야기하려면 "강력한 유형"및 "약한 유형"이라는 용어를 피하는 것이 가장 좋습니다. C는 정적으로 입력되지만 많은 허점이있는 언어라고 말할 수 있습니다. 한 가지 허점은 모든 포인터 유형을 다른 포인터 유형으로 자유롭게 캐스팅 할 수 있다는 것입니다. 또한 문제의 각 유형에 대해 하나씩 두 개의 멤버가있는 C 공용체를 선언하여 선택한 두 유형 사이에 허점을 만들 수도 있습니다.
나는 why-interpreted-langs-are-mostly-ducktyped-while-compiled-have-strong-typing 에서 정적 및 동적 타이핑에 대해 더 많이 썼습니다 .
whereas "weakly typed" means "there are loopholes in the type system
모든 언어를 '약하게'또는 '강하게'입력 한 것으로 분류하는 것은 어렵습니다. 그러나 다른 언어에 비해 C는 상당히 강력한 유형입니다. 모든 객체에는 컴파일 타임 유형이 있으며 컴파일러는 유형이 허용하지 않는 객체로 무언가를 수행하는 경우 (큰 소리로) 알려줍니다. 예를 들어 잘못된 유형의 매개 변수를 사용하여 함수를 호출하거나 존재하지 않는 구조체 / 유니온 멤버에 액세스하는 등의 작업을 할 수 없습니다.
그러나 몇 가지 약점이 있습니다. 한 가지 주요 약점은 타입 캐스트입니다. 본질적으로 객체 유형을 다루고 컴파일러는 조용해야한다고 말합니다. void*
또한 또 다른 약점입니다. 알 수없는 유형에 대한 일반적인 포인터이며이를 사용할 때 올바른 일을하고 있는지 각별히주의해야합니다. 컴파일러는 대부분의 void*
. void*
캐스트가없는 모든 유형에 대한 포인터로 변환 될 수도 있습니다 (C ++가 아닌 C에서만). 이는 또 다른 약점입니다.
이것에 대한 문헌은 명확하지 않습니다. 강력한 타이핑은 예 / 아니요가 아니라 다양한 정도의 강력한 타이핑이 있다고 생각합니다.
프로그래밍 언어에는 프로그램을 실행하는 방법에 대한 사양이 있습니다. 때때로 특정 프로그램으로 실행하는 방법이 명확하지 않습니다. 예를 들어, 숫자에서 문자열을 빼려고하는 프로그램이 있습니다. 또는 0으로 나누는 프로그램. 이러한 조건을 처리하는 방법에는 여러 가지가 있습니다. 일부 언어에는 이러한 오류를 처리하기위한 규칙이 있습니다 (예 : 예외 발생). 다른 언어에는 이러한 상황을 처리하는 규칙이 없습니다. 이러한 언어에는 일반적으로 지정되지 않은 동작을 유발하는 프로그램 컴파일을 방지하는 유형 시스템이 있습니다. 또한 지정되지 않은 동작이 있고 컴파일 타임에 이러한 오류를 방지 할 유형 시스템이없는 언어도 있습니다 (지정되지 않은 동작을 수행하는 프로그램을 작성하면 미사일을 발사 할 수 있음).
그래서:
모든 경우 (문자열에 숫자 추가 등)에서 런타임에 발생하는 작업을 지정하는 언어를 동적 유형이라고합니다. 컴파일 타임에 오류가있는 프로그램 실행을 방지하는 언어는 정적으로 입력됩니다. 어떤 일이 발생하는지 지정하지 않고 오류를 방지 할 유형 시스템이없는 언어를 약한 유형이라고합니다.
그렇다면 Java는 정적으로 입력됩니까? 예, 그 유형 시스템은 숫자에서 문자열을 빼는 것을 허용하지 않기 때문입니다. 아니요, 0으로 나눌 수 있기 때문입니다. 타입 시스템을 사용하면 컴파일 타임에 0으로 나누는 것을 방지 할 수 있습니다. 예를 들어 0이 될 수없는 숫자 유형 (예 : NonZeroInt)을 만들고이 유형의 숫자로만 나눌 수 있습니다.
그렇다면 C는 강력하게 입력됩니까 아니면 약하게 입력됩니까? C는 유형 시스템이 일부 유형 오류를 허용하지 않기 때문에 강력하게 입력됩니다. 그러나 어떤 일이 발생하는지 정의되지 않은 다른 경우에는 약하게 입력됩니다 (유형 시스템이 사용자를 보호하지 않음).
int
값이 사용자 또는 명령 줄 인수 또는 파일에서 값을 가져 오면 컴파일러가 0이되는 것을 막을 수있는 방법이 없습니다!
C는 컴파일러 오류없이 캐스트를 통해 모든 유형을 다른 유형으로 변환 할 수 있으므로 약한 유형으로 간주됩니다. 여기 에서 문제에 대한 자세한 내용을 읽을 수 있습니다 .
C는 Javascript보다 더 강력하고 Ada보다 덜 강력합니다.
나는 그것이 연속체의 강하게 타이핑 된쪽에 더 많이 떨어진다고 말하고 싶습니다. 그러나 다른 누군가가 동의하지 않을 수 있습니다 (그들이 틀렸더라도).
그것은 어떻게 결정적입니까?
C는 정적으로 형식화 된 것으로 간주됩니다 (int에서 float로 변수를 변경할 수 없음). 변수가 선언되면 그런 식으로 고정됩니다.
그러나 유형이 플립 플롭 될 수 있기 때문에 약한 유형으로 간주됩니다.
0은 무엇입니까? '\ 0', FALSE, 0.0 등.
많은 언어에서는 조건이 부울 표현식의 부울 값만 가져 오기 때문에 IF (변수)라고 말할 수 없습니다. 이들은 더 강력한 형식입니다. 문자와 정수 사이를 이동할 때도 마찬가지입니다.
기본적으로 c에는 두 가지 주요 단순 데이터 유형, 정수 및 부동 소수점 숫자 (다양한 정밀도)가 있습니다. 그 밖의 모든 부울, 열거 형 (간단하지는 않지만 적합) 등은 그중 하나로 구현됩니다. 문자조차 기본적으로 정수입니다.
문자열 유형, 정의 된 값에만 할당 할 수있는 열거 형 유형, 부울 또는 참 / 거짓을 생성하는 표현식 만 사용할 수있는 부울 유형이있는 다른 언어와 비교하십시오.
그러나 Perl C에 비해 강력한 유형이라고 주장 할 수 있습니다. 그래서 이것은 유명한 주장 중 하나입니다 (vi vs emacs, linux vs windows 등). C #은 C보다 강력한 형식입니다. 기본적으로 어느 쪽이든 주장 할 수 있습니다. 그리고 당신의 대답은 아마도 양방향으로 갈 것입니다 :) 또한 일부 교과서 / 웹 페이지에서는 C가 약하게 입력되고 일부는 C가 강하게 입력되었다고 말합니다. 위키피디아에 가면 C 항목이 "부분적으로 약한 타이핑"이라고 말합니다. 파이썬 C에 비해 약한 유형이라고 말할 수 있습니다. 그래서 Python / C #, C, Perl은 연속체입니다.
여기에 많은 좋은 답변이 있습니다. Real World Haskell 에서 중요한 점을 말씀 드리고 싶습니다 .
많은 언어 커뮤니티가 "강력한 유형"에 대한 자체 정의를 가지고 있다는 사실을 아는 것이 유용합니다. 그럼에도 불구하고 우리는 타입 시스템의 강점 개념에 대해 짧고 폭넓게 이야기 할 것입니다.
(한조각)
활자체를 둘러싼 불꽃 놀이는 사람들이 "약함"과 "강함"이라는 단어에 가치관을 붙이는 평범한 영어에 뿌리를두고 있습니다. 우리는 보통 힘을 약점보다 낫다고 생각합니다. 더 많은 프로그래머가 학문적 전문 용어보다 평범한 영어를 사용하며, 학자들은 실제로 자신의 취향에 맞지 않는 유형 시스템에 벽돌 박쥐를 던지고 있습니다. 그 결과 종종 인기있는 인터넷 오락, 화염 전쟁이 발생합니다.
따라서 C 및 C ++에 대한 답변을 살펴 보지만 '강함'과 '약함'은 '좋음'과 '나쁨'에 매핑되지 않습니다.
강력하게 입력 된 용어 에 동의 된 정의가 없습니다. 따라서 "강하게 입력 함" 이 의미 하는 바를 정의하지 않으면 질문에 대답 할 수 없습니다.
내 경험상 "강하게 입력 된"및 "약하게 입력 된"이라는 용어는 트롤에 의해 독점적 으로 사용됩니다 . 왜냐하면 정의가 없기 때문에 트롤이 자신의 의제에 맞게 중간 인수를 재정의 할 수 있기 때문입니다. 화염 전쟁을 시작하는 것 외에는이 용어는 거의 쓸모가 없습니다.
강력한 형식의 언어의 주요 측면은 무엇입니까?도 살펴볼 수 있습니다. 여기 StackOverflow에 있습니다.
질문의 이유는 무엇입니까? 내가 묻는 이유는 이것이 일종의 사소한 차이이며 "강력한 유형"의 특정 사용에는 다소 설명이 필요할 수 있기 때문입니다. Java 및 기타 언어에는 암시 적 유형 대화에 대해 더 엄격한 제한이 있다고 분명히 말하고 싶습니다.
"강력한 유형"에 대한 구체적인 정의가없는 경우 구체적인 답변을 제공하기가 어렵습니다. C는 모든 변수와 모든 표현식에 유형이 있지만 캐스트를 사용하여 유형을 변경하고 한 유형의 표현을 다른 유형으로 재 해석 할 수 있다는 점에서 약한 유형이라는 점에서 강력한 유형이라고 말할 수 있습니다.
C는 컴파일러 / 플랫폼이 지시하는 것처럼 강력하게 입력되었다고 말할 수 있습니다. 예를 들어 엄격한 플랫폼에서 빌드하는 경우 유형 punned 포인터를 역 참조하면 중단 될 수 있습니다.
void m_free(void **p)
{
if (*p != NULL) {
free(*p);
*p = NULL;
}
}
....
char *str = strdup("foo");
m_free((void **) &foo);
이제 컴파일러에게 엄격한 앨리어싱을 건너 뛰라고하면 문제가되지는 않지만 이식성이별로 없습니다. 따라서 그런 의미에서 언어의 한계를 뛰어 넘는 것은 가능하지만 아마도 최선의 아이디어는 아닐 것입니다. 그것은 전형적인 캐스팅을 넘어서서, 즉 int를 길게 캐스팅하고 실제로 void의 가능한 함정 중 하나를 보여줍니다.
따라서 C는 기본적으로 엄격하게 형식화되어 있지만 다양한 컴파일러는 프로그래머가 가장 잘 알고 있고 유연성을 허용한다고 가정합니다. 이것은 실제로 컴파일러에 따라 다르며 일부는 잠재적 인 죄송합니다. 따라서 그런 의미에서 선택한 컴파일러는 질문에 답할 때 실제로 역할을합니다. 옳은 것은 종종 컴파일러가 당신이 벗어날 수 있도록 허용하는 것과 다릅니다.
강력하게 입력되지 않았습니다.
다음 함수 프로토 타입이 인수의 데이터 유형에 대해 알려주는 내용을 고려하십시오.
void func (int n, char ch, ...);
아무것도. 따라서 여기에는 강력한 타이핑이 적용되지 않는 것이 좋습니다.
모든 표현식이 그 값의 함수가 아닌 유형을 가지고 있기 때문에 이것이 강력한 유형이라고 말하고 싶습니다. ei는 런타임 전에 알 수 있습니다.
OTOH 이것이 강력하게 입력 된 올바른 설명인지 잘 모르겠습니다. 언어에 대한 이유를 알 수있는 유일한 강력한 주장은 유형 캐스트, 공용체, 다른 언어로의 호출, 포인터, 어셈블리 언어 등을 통해 런타임에 유형 시스템을 파괴 할 수 없다는 보장입니다. 이와 같은 언어 존재하지만 너무 불구가되어 높은 확신과 학계를 벗어난 프로그래머에게는 그다지 관심이없는 것 같습니다. 누군가가 지적했듯이 실제로 제대로 수행하려면 다음과 같은 유형이 필요하기 시작 nonZeroInt
합니다. 왝.