programing

부호가 없는 문자를 문자로 바꿀 수 있나요?

sourcetip 2022. 8. 15. 10:13
반응형

부호가 없는 문자를 문자로 바꿀 수 있나요?

다음과 같은 데이터를 기대하는 기능을 사용하고 싶다.

void process(char *data_in, int data_len);

즉, 실제로는 몇 바이트를 처리하고 있는 것입니다.

그러나 raw 바이트에 관해서는 "부호 없는 문자"를 사용하는 것이 더 편합니다(양수 0~255개의 값만 처리하는 것이 더 "권리"하다고 느끼는 것). 그래서 질문합니다.

할 수 요?unsigned char *이수함 함함?

즉, 다음과 같습니다.

  • 정보의 손실 없이 자유롭게 문자/부호 없는 문자를 변환(캐스트)할 수 있는 것이 보증됩니까?
  • 정보를 잃지 않고 원하는 대로 포인터와 부호 없는 문자를 안전하게 변환(캐스팅)할 수 있습니까?

보너스: 정답은 C와 C++로 같습니까?

즉, 명시적 캐스트를 사용하는 경우에는 '그렇다'고 대답할 수 있지만, 자세히 설명하자면 다음과 같은 세 가지 측면을 살펴볼 수 있습니다.

1) 전환의 적법성
「」의 signed T* ★★★★★★★★★★★★★★★★★」unsigned T* 타입의 )T에 source type으로 할 수 있기 때문에 어느 으로도 일반적으로 void *과 (「4.10」)입니다.void *는, 명시적인 할 수 있습니다.static_cast (제5.2.9/13호):

static_cast<unsigned char*>(static_cast<void *>(data_in))

이것은 다음과 같이 생략할 수 있다(「5.2.10/7」).

reinterpret_cast<unsigned char *>(data_in)

char는 표준 규격 타입(33.9.1/7,8 및 §3.9/9)이며 서명성은 얼라인먼트를 변경하지 않습니다(33.9.1/1).다.

(unsigned char *)(data_in)

역시 , 하다, 하다, 하다, 하다, unsigned*로로 합니다.signed*시시시돌돌돌다또, 이 순서를 편도로 적용하면, 포인터 값(즉, 포인터가 가리키는 주소)이 변경되지 않는 것을 보증합니다( that5.2.10/7).

것이 다 '아까 하다'의 되는 것은 .signed char * ★★★★★★★★★★★★★★★★★」unsigned char *, .char */unsigned char * ★★★★★★★★★★★★★★★★★」char */signed char *char,signed char ★★★★★★★★★★★★★★★★★」unsigned char공식적으로 제3.9.1/1조의 세 가지 다른 유형이다.)

확실히 하자면, 세 가지 주조 방법 중 어느 것을 사용하든 상관 없지만, 한 가지 방법을 사용해야 합니다.포인터를 건네주는 것만으로, 변환은 표준 변환이 아니기 때문에, 암묵적으로 행해지지 않습니다(컴파일러가 시도하면 에러를 발행합니다.

2) 2) 값에 대한
즉 를 참조 해제하면 어떻게 ?*data_inglvalue로 하다것이이잘잘의의?????????여기서 관련된 규칙은 엄밀한 에일리어싱 규칙(「3.10/10」)입니다.

프로그램이 다음 유형 중 하나 이외의 glvalue를 통해 객체의 저장된 값에 액세스하려고 하면 동작은 정의되지 않습니다.

  • [...]
  • 객체의 동적 유형에 대응하는 부호 있는 유형 또는 부호 없는 유형입니다.
  • [...]
  • a char ★★★★★★★★★★★★★★★★★」unsigned chardiscloss.discloss.

「」, 「」에 합니다.signed char (오류)charunsigned char* (오류)char에서는 그 되지 않습니다 할 수 .)이러한 조작은 문제없이 실시할 수 있을 것입니다.

3) 결과값
유형 변환된 포인터를 디프로피드한 후 얻은 값으로 작업할 수 있습니까?위에서 설명한 포인터의 변환과 참조는 문자 주소에 저장된 비트 패턴을 재해석(변경하지 않음)하는 것과 같다는 점에 유의하십시오.그러면 부호 있는 문자의 비트 패턴이 부호 없는 문자의 비트 패턴으로 해석되면(또는 그 반대) 어떻게 됩니까?

부호 없음에서 부호 있음으로 이행할 경우 일반적으로 0 ~128의 값은 아무 일도 일어나지 않고 128을 초과하는 값은 음이 됩니다.역방향에서도 유사:부호 있는 값에서 부호 없는 값으로 이동하는 경우 음수 값이 128보다 큰 값으로 표시됩니다.

그러나 이러한 행동은 기준서에 의해 실제로 보장되지 않는다.이 기준서가 보장하는 유일한 것은 세 가지 유형 모두에 대해char,unsigned char ★★★★★★★★★★★★★★★★★」signed char8, btw로 하다따라서 하나의 복사본을 다른 것으로 해석하여 몇 개의 복사본을 만든 후 원래 위치에 저장하면 (필요에 따라) 정보가 손실되지 않는다는 것을 확신할 수 있지만, 값이 실제로 무엇을 의미하는지 알 필요는 없습니다(적어도 완전히 휴대할 수 있는 방법은 아닙니다.

네, 언제든지 char에서 부호 없는 char로 변환할 수 있습니다.다음 코드를 실행하여 ASCII 테이블(http://www.asciitable.com/), 참조)과 비교하면 증명과 C/C++가 변환에 어떻게 대처하는지 확인할 수 있습니다.이러한 코드도 같은 방법으로 처리됩니다.

#include "stdio.h"


int main(void) {
    //converting from char to unsigned char
    char c = 0;
    printf("%d byte(s)\n", sizeof(char));  // result: 1byte, i.e. 8bits, so there are 2^8=256 values that a char can store.
    for (int i=0; i<256; i++){
        printf("int value: %d - from: %c\tto: %c\n", c,  c, (unsigned char) c);
        c++;
    }

    //converting from unsigned char to char
    unsigned char uc = 0;
    printf("\n%d byte(s)\n", sizeof(unsigned char));
    for (int i=0; i<256; i++){
        printf("int value: %d - from: %c\tto: %c\n", uc, uc, (char) uc);
        uc++;
    }
}

라인이 너무 많아서 출력 안 올릴게요!각 섹션의 전반, 즉 i=0:190부터의 출력에서는 문자에서 부호 없는 문자로의 변환이 수정이나 손실 없이 잘 기능하는 것을 알 수 있습니다.

단, i=128:255부터는 문자 및 부호 없는 문자를 캐스트할 수 없습니다.부호 없는 문자는 [0:256]의 값을 저장하고 char는 [-128:255]의 간격으로 값을 저장하기 때문에 출력은 다릅니다.단, C/C++에서는 일반적으로 ASCII 문자로 chars/unsigned chars만 선두에 두고 128개의 다른 값(chars는 양수, 부호 없는 chars는 음수)을 사용할 수 없기 때문에 이 후반부의 동작은 관계가 없습니다.

문자를 나타내지 않는 문자에 값을 넣지 않고 문자를 나타내지 않는 부호 없는 문자에 값을 넣지 않으면 모든 것이 정상입니다.

extra: 문자열에 UTF-8 또는 기타 부호화(특수문자용)를 C/C++로 사용하는 경우에도 이러한 종류의 캐스트를 사용하는 것은 모두 OK입니다.예를 들어 UTF-8 부호화(http://lwp.interglacial.com/appf_01.htm) 참조:

char hearts[]   = {0xe2, 0x99, 0xa5, 0x00};
char diamonds[] = {0xe2, 0x99, 0xa6, 0x00};
char clubs[]    = {0xe2, 0x99, 0xa3, 0x00};
char spades[]   = {0xe2, 0x99, 0xa0, 0x00};
printf("hearts (%s)\ndiamonds (%s)\nclubs (%s)\nspades (%s)\n\n", hearts, diamonds, clubs, spades);

은 다음과
) 하((♥)
)
) 클럽(♣)
)스페이드(♠)

각각의 문자를 부호 없는 문자로 변환하더라도 말이죠.

따라서:

  • "이 함수에 부호 없는 문자 *를 항상 안전하게 전달할 수 있습니까?"네!

  • "정보 손실 없이 원하는 대로 문자 및 부호 없는 문자 간에 안전하게 변환(캐스팅)할 수 있는 것이 보장됩니까?"네!

  • "정보 손실 없이 원하는 대로 포인터와 부호 없는 문자를 안전하게 변환(캐스트)할 수 있습니까?"네!

  • "C와 C++의 답은 같습니까?"네!

의미론적으로, 사이의 전달unsigned char * ★★★★★★★★★★★★★★★★★」char *c+++로

단, 다음 샘플코드를 검토해 주십시오.

#include "stdio.h"

void process_unsigned(unsigned char *data_in, int data_len) {
    int i=data_len;
    unsigned short product=1;

    for(; i--; product*=data_in[i]) 
        ;

    for(i=sizeof(product); i--; ) {
        data_in[i]=((unsigned char *)&product)[i];
        printf("%d\r\n", data_in[i]);
    }
}

void process(char *data_in, int data_len) {
    int i=data_len;
    unsigned short product=1;

    for(; i--; product*=data_in[i]) 
        ;

    for(i=sizeof(product); i--; ) {
        data_in[i]=((unsigned char *)&product)[i];
        printf("%d\r\n", data_in[i]);
    }
}

void main() {
    unsigned char 
        a[]={1, -1}, 
        b[]={1, -1};

    process_unsigned(a, sizeof(a));
    process(b, sizeof(b));
    getch();
}

출력:

0255-1-1

에 있는 모든 process_unsigned ★★★★★★★★★★★★★★★★★」process그냥 똑같아요.유일한 차이점은 서명되지 않은 것과 서명되지 않은 것입니다.이 예에서는, 블랙 박스내의 코드가 SIGN 의 영향을 받지 않고, 착신측과 발신측 사이에 아무것도 보증되지 않는 것을 나타내고 있습니다.

따라서 합격만 가능하지만 다른 가능성은 전혀 보장되지 않습니다.

unsigned char ★★★★★★★★★★★★★★★★★」signed char단지 해석일 뿐입니다. 전환은 일어나지 않습니다.

바이트를 처리 중이므로 의도를 나타내려면 다음과 같이 선언하는 것이 좋습니다.

void process(unsigned char *data_in, int data_len);

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」char는 부호 있는 유형 또는 부호 없는 유형일 수 있습니다. 및 어느쪽인가를 하고 있습니다(C++ 규격은, C++ 규격, C++ 규격, C+ 규격, C++ 규격, C++ 규격, C+ 규격, C++ 규격, C++ 규격, C++ 규격, C++ 규격의 는 항상 별개의 입니다).unsigned char ★★★★★★★★★★★★★★★★★」signed char그 중 있습니다 ], 단, 그, 그, 그, 그, ,, ,, ,, ,, ,, ,, , but , , , , , 。

는 다른 의 포인터에 할 수 .char을 해야 할 도 있습니다.포인터는 반드시 같은 사이즈와 같은 값이어야 합니다.변환하는 동안 정보 손실은 없습니다.

「」를 char로로 합니다.unsigned char에서는 IP 1을 .char을 ""로 합니다.unsigned char를 지정합니다.char을 매기다unsigned char.

unsigned char로로 합니다.char데이터 손실은 조금 어렵지만 여전히 가능합니다.

#include <limits.h>

char uc2c(unsigned char c)
{
#if CHAR_MIN == 0
  // char is unsigned
  return c;
#else
  // char is signed
  if (c <= CHAR_MAX)
    return c;
  else
    // ASSUMPTION 1: int is larger than char
    // ASSUMPTION 2: integers are 2's complement
    return c - CHAR_MAX - 1 - CHAR_MAX - 1;
#endif
}

는 이 함수로 변환합니다.unsigned char로로 합니다.char을 같은 으로 수 unsigned char값어치

요.process()서명되지 않은 문자를 안전하게 통과시킬 수 있는지 확인합니다.함수가 문자를 배열의 인덱스로 사용하는 경우, 서명되지 않은 데이터는 사용할 수 없습니다.

언급URL : https://stackoverflow.com/questions/15078638/can-i-turn-unsigned-char-into-char-and-vice-versa

반응형