부호가 없는 문자를 문자로 바꿀 수 있나요?
다음과 같은 데이터를 기대하는 기능을 사용하고 싶다.
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_in
glvalue로 하다것이이잘잘의의?????????여기서 관련된 규칙은 엄밀한 에일리어싱 규칙(「3.10/10」)입니다.
프로그램이 다음 유형 중 하나 이외의 glvalue를 통해 객체의 저장된 값에 액세스하려고 하면 동작은 정의되지 않습니다.
- [...]
- 객체의 동적 유형에 대응하는 부호 있는 유형 또는 부호 없는 유형입니다.
- [...]
- a
char
★★★★★★★★★★★★★★★★★」unsigned char
discloss.discloss.
「」, 「」에 합니다.signed char
(오류)char
를 unsigned char*
(오류)char
에서는 그 되지 않습니다 할 수 .)이러한 조작은 문제없이 실시할 수 있을 것입니다.
3) 결과값
유형 변환된 포인터를 디프로피드한 후 얻은 값으로 작업할 수 있습니까?위에서 설명한 포인터의 변환과 참조는 문자 주소에 저장된 비트 패턴을 재해석(변경하지 않음)하는 것과 같다는 점에 유의하십시오.그러면 부호 있는 문자의 비트 패턴이 부호 없는 문자의 비트 패턴으로 해석되면(또는 그 반대) 어떻게 됩니까?
부호 없음에서 부호 있음으로 이행할 경우 일반적으로 0 ~128의 값은 아무 일도 일어나지 않고 128을 초과하는 값은 음이 됩니다.역방향에서도 유사:부호 있는 값에서 부호 없는 값으로 이동하는 경우 음수 값이 128보다 큰 값으로 표시됩니다.
그러나 이러한 행동은 기준서에 의해 실제로 보장되지 않는다.이 기준서가 보장하는 유일한 것은 세 가지 유형 모두에 대해char
,unsigned char
★★★★★★★★★★★★★★★★★」signed char
8, 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
'programing' 카테고리의 다른 글
Android에서 문자열을 정수로 변환 (0) | 2022.08.15 |
---|---|
REST를 통해 vue-form-generator에 폼 데이터 로드 (0) | 2022.08.15 |
vuex 작업으로부터 약속을 반환하는 중 (0) | 2022.08.15 |
Vue는 본체의 스크롤 높이를 계산하거나 감시할 수 있습니까? (0) | 2022.08.15 |
errno 확인 중!= EINTR: 무슨 뜻입니까? (0) | 2022.08.15 |