Archive

Posts Tagged ‘Program’

C语言中的有符合与无符合类型

April 20th, 2009 No comments

这几天在解析ARP,ICMP 的时候, 要对数据进行移位,由于之前对unsigned 和 singned没有很好的认识,有些莫名奇怪的问题。

比如下面的代码:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define ARRAY_SIZE(arr)        (sizeof(arr) / sizeof((arr)[0]))

int main(void)
{
char mac[6] = {0×80, 0x1E, 0×37, 0x1A, 0x3D, 0x7F};

int i = 0;
for(i = 0; i<ARRAY_SIZE(mac); i++) {
printf(“0x%X “, mac[i]);
}
printf(“\n”);

write1(mac, 6);
return 0;
}

void write1(unsigned char *buf, uint16_t buf_size)
{
int i = 0;
uint16_t cur_word = 0;

for (i = 0; i < buf_size; i += 2) {
cur_word = (uint16_t)((buf[i] <<8 ) | buf[i+1]);
printf(“0x%04X buf[i] 0x%02X  buf[i+1] 0x%02X\n”, cur_word, buf[i], buf[i+1]);
}
}

border@ubuntu:~$ uname -a
Linux ubuntu 2.6.24-21-generic #1 SMP Tue Oct 21 23:43:45 UTC 2008 i686 GNU/Linux
border@ubuntu:~$ ./hello
0xFFFFFF80 0x1E 0×37 0x1A 0x3D 0x7F
0x801E buf[i] 0×80  buf[i+1] 0x1E
0x371A buf[i] 0×37  buf[i+1] 0x1A
0x3D7F buf[i] 0x3D  buf[i+1] 0x7F

怎么打印结果不同, 在主函数里面第一个打印出来的是 0xFFFFFF80, 但是在write1函数里面就是正常的0×80了,但是你有可能说
是0x%x 和 0x%02x 的问题,于是程序改为:

char mac[6] = {0x80, 0x1E, 0x37, 0x1A, 0x3D, 0x7F};
int i = 0;
for(i = 0; iprintf("0x%02X ", mac[i]);
}
printf("\n");

就算是改为 %02X,也是输出0xFFFFFF80,和%x的结果一样。

但是如果把char mac[6] 改为 unsigned char mac[6] 主函数就没有问题。

在write1函数里面,如果你把参数unsigned char *buf 改为char *buf, 当大于0x7F的时候,也会溢出,是因为C 里面如果没有定义
类型符合的话默认为singned.

singned的取之范围是-128-127(0×80-0x7F), 所以当大于0x7F的时候会溢出。

unsigned 的取值范围是0-255(0-0xFF).

如果你要进行高低段位移的话,以后要定义为unsigned.

疑问:  为什么%02X输出的也是8个字节,而不是两个字节?

Bian Jiang

http://www.wifihack.net

–EOF–

Categories: Tech.Notes Tags: , ,