(C语言)由十六进制输出所想到的 (一,引子)


最近再看网络方面的程序设计,由于tcp协议是基于字节流的形式,某时突然想到如何进行变量的十六进制输出。故此小结了一下这篇文章。

例子是用C语言给出的。

先说一下我的编程环境,我是在windows操作系统下用vs2005进行编译,cpu是intel的P4,因此那些变量的字节数分别是:

                 char  是 1 字节                        short 是 2 字节

int, long, float ,指针 是 4 字节            double,long long 是 8 字节       

VC中字符串的多字节编码和unicode编码的转化在:"项目--属性--配置属性--常规--(右边)字符集" 选项里面切换

由于用到了TCHAR 和 TEXT宏,所以要加上头文件 #include <windows.h>
先看下面的函数:

拷贝如下代码到vs2005的时候也许会把左边的数字也拷过去了,这个时候用vs2005的“编辑--查找和替换”,切换到“快速替换”,先把“查找选项”的“使用正则表达式”这项勾上,然后在“查找内容”上输入双引号里面的内容(不算双引号啊):“^ +[0-9]+/.”,“替换为 ”那个选项就不要填东西了,然后点击替换,就一个一个的替换了。(不好意思啊,语文太差,表达的太啰嗦,哂笑于各位方家了。)
  1. typedef unsigned char uchar;

  2. void printHex(uchar *str, int size)
  3. {
  4.     int index = 0;
  5.     for(index = 0; index < size; index++)
  6.         /* %x是以16进制的格式输出 */

  7.         printf("%x ", str[index]);
  8.     printf("/n");
  9. }
再看下面调用的例子:
  1. char str[] = "abcde";
  2. printHex( (uchar *)str, sizeof(str) );


  3. /* 多字节编码(gb2312或者gbk)下的中英文混合 */
  4. TCHAR ansi_str[] = TEXT("我是ABc");
  5. printHex( (uchar *)ansi_str, sizeof(ansi_str) );


  6. /* Unicode编码下的中英文混合 */
  7. TCHAR uni_str[] = TEXT("我是ABc");
  8. printHex( (uchar *)uni_str, sizeof(uni_str) );


  9. int a = 123456;
  10. printHex( (uchar *)&a, sizeof(a) );


  11. long long lg = 1234567899123;
  12. printHex( (uchar *)&lg, sizeof(lg) );


  13. float f = 123.456f;
  14. printHex( (uchar *)&f, sizeof(f) );


  15. double d = 123.45678;
  16. printHex( (uchar *)&d, sizeof(d) );


  17. struct A
  18. {
  19.     int a;
  20.     char b;
  21.     float c;
  22. };
  23. struct A aA;
  24. aA.a = 123457;
  25. aA.b = 'c';
  26. aA.c = 123.456f;
  27. printHex( (uchar *)&aA, sizeof(aA) );

 

下面来看看输出结果,内存地址是从左往右增大,为了方便,比如说输出4我下面写为04,a写为0a等等
  

  1. /* char str[] = "abcde" */
  2. 61 62 63 64 65 00

  3. /* 多字节编码下的 TCHAR ansi_str[] = "我是ABc" */
  4. ce d2 ca c7 41 42 63 00

  5. /* Unicode编码下的 TCHAR uni_str[] = "我是ABc" */
  6. 11 62 2f 66 41 00 42 00 63 00 00 00

  7. /* int a = 123456 */
  8. 40 e2 01 00

  9. /* long long lg = 1234567898123 */
  10. f3 27 fb 71 1f 01 00 00

  11. /* float f = 123.456f */
  12. 79 e9 f6 42

  13. /* double d = 123.45678 */
  14. e1 5d 2e e2 3b dd 5e 40

  15. /* struct A aA=[ (int)123457, (char)'c', (float)
  16. 123.456f ] */
  17. 41 e2 01 00 63 cc cc cc 79 e9 f6 42
下面要讨论的问题:

1. 为什么要用unsigned char作伪输入参数而不用char?(引出字符编码的细节)

2. 多字节编码和unicde编码输出的不同之处?

3. int a = 123456;的十六进制数是:0x1e240 为什么输出却是40 e2 01 00?
(引出big endian 与little endian相关的细节)

4. float f = 123.456f 的输出是怎么得到的?(引出浮点数的内存格式)

5. 结构体struct A 的变量aA的成员占了9个字节(4 + 1 + 4 = 9),为什么输出却是 12 个字节?(引出结构体的字节对齐)

下面分几节来讲:问题1,2合起来做一篇文章,问题3,4,5分别各做一篇。

先工作了,有时间再写下去,呵呵。

你可能感兴趣的:(c,windows,正则表达式,struct,语言,float)