문제

단일 바이트 정밀도로 포인터 연산을 어떻게 이식 가능하게 수행할 수 있습니까?

다음 사항을 명심하세요.

  • char 모든 플랫폼에서 1바이트가 아닙니다.
  • sizeof(void) == 1 GCC의 확장으로만 사용할 수 있습니다.
  • 일부 플랫폼에는 포인터 역참조 포인터 정렬 제한이 있을 수 있지만 산술에는 여전히 가장 작은 기본 POD 유형의 크기보다 더 미세한 세분성이 필요할 수 있습니다.
도움이 되었습니까?

해결책

당신의 가정에는 결함이 있습니다 - sizeof(char) ~이다 한정된 어디서나 1이 되는 것.

로부터 C99 표준(TC3), 섹션 6.5.3.4("sizeof 연산자")에서:

(2항)

연산자의 크기는 오페라의 크기 (바이트)를 생성하며, 이는 표현 또는 유형의 괄호 이름 일 수 있습니다.

(3항)

숯, 서명되지 않은 문자 또는 서명 된 숯이있는 피연산자에 적용하면 결과는 1입니다.

이들을 종합하면 C에서는 char의 크기가 무엇이든 해당 크기가 "바이트"라는 것이 분명해집니다(특정 플랫폼에서는 8비트를 초과하더라도).

char 따라서 주소 지정이 가능한 가장 작은 유형입니다.a보다 작은 단위로 주소를 지정해야 하는 경우 char, 당신의 유일한 선택은 다음을 읽는 것입니다 char 한 번에 비트 연산자를 사용하여 해당 부분을 마스크합니다. char 당신이 원하는 그.

다른 팁

sizeof(char) 항상 1을 반환합니다. 두 C 모두에서 그리고 C++.ㅏ char 길이는 항상 1바이트입니다.

표준에 따르면 char 주소를 지정할 수 있는 가장 작은 데이터 덩어리입니다.더 정확하게 주소를 지정할 수는 없습니다. 수동으로 포장/포장 풀기를 수행해야 합니다.

sizeof(char) 보장됩니다 1 C 표준에 따라.설사 char 9비트 이상을 사용합니다.

그래서 당신은 할 수 있습니다 :

type *pt;
unsigned char *pc = (unsigned char *)pt;

그리고 사용 pc 산수를 위해. 할당 pc 에게 pt 위의 캐스트를 사용하는 것은 C 표준에 의해 정의되지 않은 동작입니다.

만약에 char 너비가 8비트를 초과하면 이식 가능한(ANSI/ISO) C에서 바이트 정밀도 포인터 연산을 수행할 수 없습니다.여기에서 바이트, 내 말은 8 비트를 의미합니다.기본형 자체가 8비트보다 크기 때문이다.

포인터를 uintptr_t.이는 포인터 크기의 부호 없는 정수입니다.이제 이에 대해 산술을 수행한 다음 결과를 역참조하려는 유형의 포인터로 다시 캐스팅합니다.

(참고하세요 intptr_t 일반적으로 원하는 것이 아닙니다.붙이는게 더 안전해요 uintptr_t 그렇게 하지 않을 타당한 이유가 있는 경우를 제외하고!)

당신이 무슨 말을 하려는지 이해가 안 돼요 sizeof(void) GCC에서는 1입니다.입력하는 동안 char 이론적으로 C 언어에서는 1개 이상의 기본 머신 바이트로 구성될 수 있습니다. sizeof(char) 은 1이고 항상 정확히 1입니다.즉, C언어의 관점에서 보면, char 항상 1 "바이트"(머신 바이트가 아닌 C바이트)입니다.그걸 이해하고 나면, 너도 이해하게 될 거야 sizeof(void) GCC에서 1이 되는 것은 어떤 식으로든 도움이 되지 않습니다.GCC에서는 포인터 연산이 void * 포인터는 포인터 연산과 정확히 같은 방식으로 작동합니다. char * 포인터. 이는 일부 플랫폼에서 char * 그러면 너한테는 안 돼 void * 당신에게도 효과가 없을 것입니다.

어떤 플랫폼에 있다면 char 객체는 여러 머신 바이트로 구성되어 있으며 전체 머신 바이트보다 더 작은 메모리 단위에 액세스할 수 있는 유일한 방법입니다. char 개체는 비트 연산을 사용하여 전체의 필요한 부분을 "추출"하고 "수정"하는 것입니다. char 물체.C 언어는 다음보다 작은 것을 직접 처리할 방법이 없습니다. char.다시 한번 char 항상 C바이트입니다.

C99 표준은 1바이트 길이의 uint8_t를 정의합니다.컴파일러가 이 유형을 지원하지 않으면 typedef를 사용하여 정의할 수 있습니다.물론 플랫폼 및/또는 컴파일러에 따라 다른 정의가 필요합니다.모든 것을 헤더 파일로 묶고 어디에서나 사용하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top