我附上这个问题的代码应该得到设备的mac地址并打印出来。 当我将结构ifreq中的数据复制到uint8_t数组时,它可以工作,但是当我没有,我得到奇怪的结果。 查看第二行和输出的第二个字节。
#include #include #include #include #include #include #include #include int main() { uint8_t tab[6]; int i; struct ifreq one; int sd = socket(AF_PACKET, SOCK_RAW, 0); memset(&one, 0, sizeof(struct ifreq)); strcpy(one.ifr_name, "eth0"); int v = ioctl(sd, SIOCGIFHWADDR, &one); memcpy(tab, one.ifr_hwaddr.sa_data, sizeof(uint8_t) * 6); for(i=0;i<6;i++) printf("%02x:", tab[i]); printf("n"); for(i=0;i<6;i++) printf("%02x:", one.ifr_hwaddr.sa_data[i]); printf("n"); }
OUTPUT:
74:86:7A:0A:2C:6D:
74:ffffff86:7A:0A:2C:6D:
你问为什么第二个字节打印为ffffff86
而不是86
? 这是因为它已经过符号扩展。 one.ifr_hwaddr.sa_data[i]
数组声明为有符号字符数组,但tab []数组是无符号的。
printf的args都被提升为int。 无符号字符0x86被提升为0x00000086,但是当假定相同的值被签名时,它将被提升为0xFFFFFF86。
整数促销再次罢工!
由于转换说明符"x"
使用两行printf
一个unsigned int
。
要打印signed
或unsigend
int
的一半(假设为32位整数),请使用长度修改器"h"
两次:
printf("%02hhx:", one.ifr_hwaddr.sa_data[i]);
在一种情况下,您可以指定促销的方式。 在第二种情况下,你没有。 您需要促销未签名。 因此,不指定它是如何发生的,会导致问题。
如果字节是0x8f,则需要提升该值,就好像该类型是无符号的一样。 否则,保留该值需要保留符号位。
促销使价值保持不变。 因此,当它们被提升时,如何将原始位解释为值,这会产生巨大的差异。
我怀疑,one.ifr_hwaddr.sa_data是字符数组。在这种情况下,char表示签免费精选名字大全符。
因此,当通过printf的变量参数列表传递时,它被提升为int,printf将其打印为unsigned int(“x”说明符)
当从char提升为int时,编译器的目标是保留其值 – 而不是其二进制表示。
0x86是134作为十进制,被视为unsigned char和-122,被视为signed char。
134 as unsigned int表示为0x68 -122,因为int表示为0xffffff86(-1表示int为0xffffffff)
因此,打印0xffffff86。 在这种情况下(打印二进制为hex)我使用%02hhx printf说明符%hhx告诉printf将其视为无符号字符 – 仅有1个字节。
以上就是c/c++开发分享奇怪的printf()行为相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/522110.html