캐스팅은 무엇을 의미합니까?


18

CI와 같은 저수준 언어로 코딩 할 때, 캐스팅은 때때로 '이 바이트를 마치 항상이 다른 유형 인 것처럼 재 해석'하고 다른 경우에는이 값을 지능적으로이 다른 유형으로 변환하는 것을 의미합니다.

단어의 원래 의미는 무엇이며 전환을 기대할 때와 원시 해석을 기대할 때 일관성이 있습니까?


Wikipedia 기사 에서 이해하지 못하는 내용은 무엇 입니까? " 형식 변환 , 타입 캐스팅강제는 다른 방법이 ... 다른에 하나 개의 데이터 유형의 엔티티를 변경 ... 각 프로그래밍 언어 유형을 변환 할 수있는 방법에 대한 자신의 규칙이 암묵적으로 또는 명시 적이다"
모기

"던지기"의 원래 의미는 프로그래밍과 공통점이 없습니다. 여기를 참조하십시오. merriam-webster.com/dictionary/cast
Doc Brown

1
캐스트 운영자 카테고리 에서 Eric Lippert의 블로그에 대한 많은 정보 (주로 관리되는 언어 관점에서)
AakashM

1
@ gnat : 그것이 심각한 질문인지 아니면 트롤링 시도인지 확실하지 않습니다. 그러나 컴파일러가 무엇을 수행하는지 알고 싶습니다 : 변환, 캐스트 또는 강제? 경험 법칙은 무엇입니까?
Alexander Torstling

1
@DocBrown 나는 cast컴퓨팅 의미 의 용어 가 야금 의미의 주조 와 더 비슷 하다고 생각합니다 . 이에 따라 용융 금속의 모양이 금형에 부어 질 때 개혁됩니다 : britannica.com/EBchecked/topic/377665/metallurgy/81884/Casting
KChaloux

답변:


10

C 언어로 캐스팅하는 것은 다른 언어와 달리 독특합니다. 또한 결코 똑똑하지 않습니다.

C로 캐스트는 신중하게 정의 된 규칙을 사용하여 한 유형에서 다른 유형으로 값을 변환합니다. 정말로 알아야 할 경우 표준을 읽으십시오. 그렇지 않으면 요점은 다음과 같습니다.

  1. 정수 유형 간 변환은 가능하면 값을 유지합니다. 목적지에 더 많은 비트가 있으면 넓어지고 일반적으로 안전하지만 부호 확장이 필요할 수 있습니다. 더 좁 으면 비트가 손실됩니다.
  2. 포인터 유형 간 변환은 포인터 값을 유지하지만 결과는 종종 정의되지 않고 종종 이식 불가능하며 고급 시나리오에 유용합니다.
  3. 정수가 충분히 큰 경우 정수 유형과 포인터 사이의 변환은 정상이며 비트 패턴 (무엇이 발생할 수 있는지)을 유지합니다. 정수가 너무 작 으면 결과는 정의되지 않지만 유용하지 않습니다. 일반적으로 'long'은 'void *'에 대해 충분히 넓지 만 보장 할 수는 없습니다! 이런 방식으로 생성 된 포인터는 모든 종류의 흥미로운 방식으로 유효하지 않을 수 있습니다.
  4. float 형식과 정수 형식 간의 변환은 적절한 라이브러리 루틴 (반올림이 아닌 잘림)으로 정의 된 산술 변환입니다.
  5. 함수의 리턴 값을 void로 캐스트 할 수 있습니다. 나는 결코 없다. 아무것도하지 않습니다.

일부 캐스트는 내재적으로 적용되며 일부 캐스트는 경고를 발행합니다. 경고에 유의하십시오!

캐스트에 대한 사전 정의는 도움이되지 않기 때문에 무시하는 것이 가장 좋습니다. 많은 캐스트는 개종이나 강압이라는 용어로 더 잘 설명되므로 그에 대한 지식도 필요합니다.

C ++은 훨씬 더 복잡하지만, 묻지 않았습니까?


나는 세부 규칙이 아닌 경험 법칙에 관심이 있지만, 그것이 문제를 해결하는 데 도움이된다면 C 이외의 다른 언어에 관심이 있습니다.
Alexander Torstling

2
내가 여기에 준 것은 합리적입니다. 실제 저수준의 전문 C / C ++ 코드를 작성하려면 세부적인 세부 사항이 중요합니다. 대부분의 언어는 유형 변환에 이러한 종류의 문제가 없습니다. 문제가 해결되지 않으면 죄송합니다.
david.pfx

으로 변환하는 것을 제외 T*void*다시와 항상 잘 정의이다.
Miles Rout

@Miles : 실제로 원래 포인터 값을 유지하려면 T *를 U *로 변환 한 후 다시 변환해야합니다. 내 대답에서 나는 짧게 유지하기 위해 '정의되지 않은'것 만 말했다 .'cos 일부 세부 사항은 매우 지저분합니다.
david.pfx

1
@supercat : n1570 S6.3.2.3 참조. T *, U * 및 void * 간 변환 / 라운드 트리핑은 하나의 예외만으로 항상 포인터 값을 유지합니다. T *가 올바르게 정렬되지 않으면 정의되지 않은 동작입니다. 나는 당신의 요점을 받아들이지 만 그 정도까지만 받아들입니다.
david.pfx

2

웹스터 사전의이 부분은 적절한 정의를 제공합니다.

a : 액체 또는 플라스틱 형태를 금형에 붓고 압력없이 경화시켜 (물질)에 형태를 부여
b :이 공정에 의해 형성

따라서 캐스팅하기 전에 "객체"(문자 그대로 OOP 객체가 아님)는 지정된 모양 (유형)입니다. 다시 캐스트 할 때, 그 주위에 "콘크리트를 부어"새로운 형태로 만듭니다. 숫자는 육각형 정수이며, 캐스팅 후에는 사각형의 문자열을 얻게됩니다.


2
또한 : "(배우)에게 특정 역할을 할당하려면".
Kelly Thomas

예. 이것이 최고라고 확신합니다. +1.
david.pfx

2

C 캐스트를 두 그룹으로 분리하는 것이 유용 할 수 있습니다.

  1. 숫자 캐스트-한 표현간에 숫자를 변환하여 값을 유지하려고합니다. 예를 들면 (int)3.1다음과 같습니다 3. 정확한 값을 유지할 수 없을 때 발생하는 일을 정의하는 정확한 규칙이 있습니다.

  2. 포인터 캐스트-메모리 주소를 유지하지만 역 참조되는 방식을 변경합니다. 에 대해 예를 들어 float x=3.5, *(int *)&x줄 것이다 1080033280- 이것은 정수 플로트를 나타내는 동일한 비트 패턴으로 표현된다 3.5.


Keep the memory address, but change the way it's dereferenced.유형 천공 포인터의 역 참조는 정의되어 있지 않습니다. 표준은 보장에서 캐스팅 A *B *같은 생산합니다 및 다시 A *또는 경우 있음 - 1 위의 역 참조에 유효하지 않았을 수있는, B *이다 char *, 모든 유형의 객체 표현을 읽을 수 있습니다합니다. 다른 모든 유형의 경우 역 참조 B *포인터는 유형 punning, UB이며 엄격한 앨리어싱을 위반합니다. 어쨌든, 컴파일러가 이런 이유로 위의 예제 2를 폐기하지 않더라도 비트 패턴에 대한 이식 불가능한 가정을하고 있습니다.
underscore_d

1
cast (v): to receive form in a mold

C ++에서는 다양한 종류의 캐스트를보다 명확하게 만들 수 있습니다. reinterpret_cast"이 바이트를 마치 이미 다른 것으로 취급합니다"라는 의미입니다. C에서는 연산자 를 사용하여 union캐스팅 (type)하면 결과를 숫자 손실과 같은 정밀도로 유지하려고 시도합니다.


2
C에서 포인터 캐스트는 항상 재 해석되며 값 캐스트는 항상 최상의 값을 유지합니다. C ++에는 포인터 캐스트를 수행하는 여러 가지 방법이 있으므로 더 명확한 캐스트 유형이 있습니다.
Jan Hudec

C 포인터 캐스트 의미론이 반드시 "재 해석"되는 것은 아닙니다. 워드 어드레싱을 사용했지만 바이트 기반 코드와 잘 상호 작용하여 int*하나의 단어와 char*두 단어 인 [두 번째 바이트가 단어의 높은 바이트 또는 낮은 바이트를 선택하는 것] 을 갖기를 원했던 프로세서에게는 합법적입니다 . 캐스팅 (int*)하는 것은 (char*)의 첫 번째 바이트를 지정합니다 어떤 값이어야합니다 여분의 단어를 추가 할 필요 int.
supercat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.