(BYTE *) 과 (BYTE ) 타입캐스팅에 관하여

koddakgi의 이미지

1.sprintf(Hex ,"%02X", (BYTE)(inData+i));
2.sprintf(Hex ,"%02X", (BYTE *)(inData+i));
3.sprintf(Hex ,"%02X", *(inData+i));
c든 C++ 이든 1과2가 다르죠?(옆에서 자꾸 같다고 우기길래)
제가 C++을 잘몰라서....
C++에서 2번과같이 하니까 값이 제대로 나온다고 합니다.
c와 C++이 다른겁니까?
마지막으로 c에서는 3번과 같이 하면 되는데
C++에선는 결과값이 다르게 나온다고 합니다.

테스트는 비주얼C++(우기는사람)과 UNIX-C[AIX5.0](저) 에서 하였습니다.

wafe의 이미지

당연히 inData는 배열 혹은 포인터라고 생각하겠습니다.

inData+i 역시 포인터이고, x86에서 포인터는 4바이트짜리 값입니다(AIX가 돌아가는 머신도 32bit 머신인가요?). 1번은 4바이트 짜리 포인터 값을 1바이트 짜리로 바꾸는 것이고, 2번은 그냥 포인터가 가리키는 변수의 타입만 바꿀 뿐이지 포인터의 값을 변환하지는 않습니다. 따라서 1번과 2번이 같게 나올리가 없고, 제가 VC++에서 확인해본 바로도 그렇습니다.

*(inData+i) 는 inData[i]와 의미가 같습니다. 여기서 제대로된 값이 나오지 않는다는걸 이해할 수 없네요. inData의 타입을 알 수 없어서 자세히는 모르겠지만, 읽어오기를 원하는 타입과 inData의 타입이 달라서 그런 문제가 생기는 것은 아닙니까?

Heejoon Lee

winner의 이미지

Visual C++ 에서는 keyword 의 많은 type 이 재정의되어서 쓰는데 솔직히 저는 싫더군요.

체스맨의 이미지

3이 다를 수 있다면 지금 테스트 상황을 잘 고려해보세요.
비쥬얼 C++ 을 쓰는 little-endian 머쉰과 aix 의 big-endian 머쉰의
차이일 가능성도 생각해보세요.

특히 이진 파일을 읽어서 배열에 저장 한 것이나 네트워크에서 전송된
이진데이터라면 충분히 차이가 있을 수 있지요.

Orion Project : http://orionids.org

koddakgi의 이미지

binary 를 Hexa로 변환하는 모듈입니다.

void CTest2App::BinaryToHex(int inCount, char *inData, char *outData)
{
    int cnt=0;
    char oneHex[3];

	for( cnt=0 ; cnt<inCount ; cnt++ )
	{
	        memset(oneHex, NULL, sizeof(oneHex));
	        sprintf(oneHex, "%02x", *(inData+cnt));
	        strncpy(outData+(cnt*2), oneHex, 2);
	}

	return ;
}

이렇게 해서 트레이스를 걸어서 추적하다보니
cnt 값이 전혀 엉뚱한 값이 나오더군요.
이게 틀린겁니까?
그래서
1.sprintf(oneHex, "%02x", (BYTE *)(inData+cnt));
혹은
2.sprintf(oneHex, "%02x", (BYTE )(*(inData+cnt)));
이렇게 수정하니까 제대로 된다고 하더군요.
2번은 가능할것같은데 1번은 틀린거 아닙니까?
x포맷이 둘다 가능한겁니까?
그럼 오늘도 수고들 하십시요
참고로 AIX컴파일러는 32bit머신 맞습니다. 맞고요
네트웍상의 데이터는 아닙니다.

여자는 도대체 무엇으로 사는가?

lunarainbow의 이미지

koddakgi wrote:
1.sprintf(oneHex, "%02x", (BYTE *)(inData+cnt));
혹은
2.sprintf(oneHex, "%02x", (BYTE )(*(inData+cnt)));
이렇게 수정하니까 제대로 된다고 하더군요.

제가 문제를 잘못 이해한 것인지... 아님 모르는거였는지는 모르겠지만,

전혀 다른 의미로 사용된듯 싶습니다.

일단 선언이 char *inData로 되어 있으니..

(BYTE*)(inData+cnt)

이것의 의미는, inData가 가진 주소값에 cnt만큼 더한 후, 그것의 값을 출력하는데, inData의 값 자체가 주소값이니... 그 주소에 cnt만큼 더해진 값을 출력하게 되는데, (BYTE*) 때문제 BYTE*형으로 케스팅되어 주소를 출력(그치만 의미는 없는)하게 되고...

(BYTE )(*(inData+cnt))

이것의 의미는 inData에 cnt만큼 더했는데... 앞에 *가 있으니 "이건 주소다! 그러니깐 일단 따라가서 값을 확인해 보라구" 하는 의미가 되니, 실제 값을 얻어오겠네요. 그런데 그 값을 (BYTE)형으로 케스팅 해주니, 1바이트 signed(BYTE가 signed 맞나요? 전 그냥 char 사용해서 모르겠네요.) 정수형으로 케스팅 되어 16진수로(%02x때문에) 출력되겠네요.

결론적으로.. 문법적으론 둘다 맞지만은 원하는 결과가 무엇인지에 따라 선택되어야 하는것이 아닐까 싶습니다. ;;;

위에서 말씀 하신 대로는, 두번째를 의도하시는것 같습니다.

ps.

참고로 AIX컴파일러는 32bit머신 맞습니다. 맞고요 
네트웍상의 데이터는 아닙니다.

다른 이야기지만, "맞습니다. 맞고요" 이건 무슨 의도로 사용 하신 것인지...

ㅡ,.ㅡ;;의 이미지

koddakgi wrote:
binary 를 Hexa로 변환하는 모듈입니다.
void CTest2App::BinaryToHex(int inCount, char *inData, char *outData)
{
    int cnt=0;
    char oneHex[3];

	for( cnt=0 ; cnt<inCount ; cnt++ )
	{
	        memset(oneHex, NULL, sizeof(oneHex));
	        sprintf(oneHex, "%02x", *(inData+cnt));
	        strncpy(outData+(cnt*2), oneHex, 2);
	}

	return ;
}

이렇게 해서 트레이스를 걸어서 추적하다보니
cnt 값이 전혀 엉뚱한 값이 나오더군요.
이게 틀린겁니까?
그래서
1.sprintf(oneHex, "%02x", (BYTE *)(inData+cnt));
혹은
2.sprintf(oneHex, "%02x", (BYTE )(*(inData+cnt)));
이렇게 수정하니까 제대로 된다고 하더군요.
2번은 가능할것같은데 1번은 틀린거 아닙니까?
x포맷이 둘다 가능한겁니까?
그럼 오늘도 수고들 하십시요
참고로 AIX컴파일러는 32bit머신 맞습니다. 맞고요
네트웍상의 데이터는 아닙니다.

ㅡㅡ;; 틀렸다는 기준이 먼가요?
에러가난다는말씀인가요 원하는 값이 안나온다는듯인가요?
원하는값은먼가요? 번지수인가요? 값인가요?가능하긴 둘다 가능하죠
1번은번지를출력하고 2번은값을출력하죠


----------------------------------------------------------------------------

wafe의 이미지

ㅡ,.ㅡ;; wrote:

ㅡㅡ;; 틀렸다는 기준이 먼가요?
에러가난다는말씀인가요 원하는 값이 안나온다는듯인가요?
원하는값은먼가요? 번지수인가요? 값인가요?가능하긴 둘다 가능하죠
1번은번지를출력하고 2번은값을출력하죠

2진값을 16진 값으로 바꾸는 프로그램이라고 하는데, 주소를 읽어오는 거니까 틀린거죠. -_-;;

1번의 경우 단지 주소값일 뿐인데 값이 제대로 나온다고 하니 이상하네요... 그분이 원하시는게 주소값은 아닐텐데 말이죠. -_-a

음 그리고, win32에서 BYTE의 정의는 요겁니다.

typedef unsigned char BYTE;

Heejoon Lee

lunarainbow의 이미지

wafe wrote:
음 그리고, win32에서 BYTE의 정의는 요겁니다.
typedef unsigned char BYTE;

unsigned 였군요.

윈도우에서 플밍 경험은 거의 없어서... 8)

koddakgi의 이미지

제질문의 요지는 sprintf의 두번째인자 "%02x"는 int 값을 원하는데
포인터값을 줘도 된다고하니
이해가 안가서 질문을 한겁니다.
"맞습니다 맞고요"의 의미는 32bit 머신이 맞다는겁니다.
BYTE가 unsignd char 의 다른이름이었군요.
아무튼 다들 고맙습니다.

여자는 도대체 무엇으로 사는가?

wafe의 이미지

koddakgi wrote:
제질문의 요지는 sprintf의 두번째인자 "%02x"는 int 값을 원하는데
포인터값을 줘도 된다고하니
이해가 안가서 질문을 한겁니다.
"맞습니다 맞고요"의 의미는 32bit 머신이 맞다는겁니다.
BYTE가 unsignd char 의 다른이름이었군요.
아무튼 다들 고맙습니다.

32bit 컴퓨터에서 주소는 32bit 정수입니다. 32bit 컴퓨터에서 int와 long은 32bit 정수입니다. 그래서 주소값이 필요한 곳에 int나 long을 넣을 수 있습니다.

Heejoon Lee

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.