在 c 中转换整个指针后,是否有必要转换指针的各个索引?为什么?
Is it necessary to cast individual indices of a pointer after you cast the whole pointer in c? Why?
在下面的代码中,ip 地址被转换为 uint8_t *。
但是下面再次将转换指针的每个索引转换为 uint8_t。
程序员为什么要这样做?如果我们删除所有那些在初始演员表之后出现的演员表,会有什么不同吗?此代码将 IPv4 IP 地址转换为 IP 编号。谢谢
uint32_t Dot2LongIP(char* ipstring)
{
uint32_t ip = inet_addr(ipstring);
uint8_t *ptr = (uint8_t *) &ip;
uint32_t a = 0;
if (ipstring != NULL) {
a = (uint8_t)(ptr[3]);
a += (uint8_t)(ptr[2]) * 256;
a += (uint8_t)(ptr[1]) * 256 * 256;
a += (uint8_t)(ptr[0]) * 256 * 256 * 256;
}
return a;
}
取消引用 ptr
的任何索引(即 ptr[0]
、ptr[1]
等)的类型将是 uint8_t
。对它们执行的转换是多余的。
Why the programmer has done this?
无知、恐惧或其他无能。
ptr
的类型是uint8_t *
,所以ptr[i]
的类型是uint8_t
。将 uint8_t
转换为 uint8_t
没有任何效果。另外,放在括号里是没有效果的。
Does it make a difference if we remove all those casts that come after the initial cast?
是的,它使代码更小更清晰。它对程序语义没有影响。
This code converts an IPv4 IP Address to an IP Number.
不,不是,不正确;代码已损坏。
当 uint8_t
值用于乘以 256 时,将应用通常的算术转换。这些将 uint8_t
提升为 int
,然后 *
运算符的结果是 int
。对于 ptr[0]
,由于执行了两次 256 的乘法运算,结果仍然是 int
。不幸的是,如果设置了 ptr[0]
的高位(第 7 位),这些乘法会溢出 32 位 int
。那么程序的行为不是C标准定义的。
为避免这种情况,值应转换为 uint32_t
。 (这只是为了让算术正确;我没有断言拆开 inet_addr
返回的 in_addr_t
并以这种方式重新组合它的有用性。)
我怀疑那是Arduino代码:)
uint32_t Dot2LongIP(char* ipstring)
{
uint32_t ip = inet_addr(ipstring);
return return nothl(ip);
}
或者如果您不想使用 htonl
uint32_t Dot2LongIP(char* ipstring)
{
uint32_t ip = inet_addr(ipstring);
ip = ((ip & 0xff000000) >> 24) | ((ip & 0x00ff0000) >> 8) |
((ip & 0x0000ff00) << 8) | ((ip & 0x000000ff) << 24);
return ip;
}
在下面的代码中,ip 地址被转换为 uint8_t *。 但是下面再次将转换指针的每个索引转换为 uint8_t。 程序员为什么要这样做?如果我们删除所有那些在初始演员表之后出现的演员表,会有什么不同吗?此代码将 IPv4 IP 地址转换为 IP 编号。谢谢
uint32_t Dot2LongIP(char* ipstring)
{
uint32_t ip = inet_addr(ipstring);
uint8_t *ptr = (uint8_t *) &ip;
uint32_t a = 0;
if (ipstring != NULL) {
a = (uint8_t)(ptr[3]);
a += (uint8_t)(ptr[2]) * 256;
a += (uint8_t)(ptr[1]) * 256 * 256;
a += (uint8_t)(ptr[0]) * 256 * 256 * 256;
}
return a;
}
取消引用 ptr
的任何索引(即 ptr[0]
、ptr[1]
等)的类型将是 uint8_t
。对它们执行的转换是多余的。
Why the programmer has done this?
无知、恐惧或其他无能。
ptr
的类型是uint8_t *
,所以ptr[i]
的类型是uint8_t
。将 uint8_t
转换为 uint8_t
没有任何效果。另外,放在括号里是没有效果的。
Does it make a difference if we remove all those casts that come after the initial cast?
是的,它使代码更小更清晰。它对程序语义没有影响。
This code converts an IPv4 IP Address to an IP Number.
不,不是,不正确;代码已损坏。
当 uint8_t
值用于乘以 256 时,将应用通常的算术转换。这些将 uint8_t
提升为 int
,然后 *
运算符的结果是 int
。对于 ptr[0]
,由于执行了两次 256 的乘法运算,结果仍然是 int
。不幸的是,如果设置了 ptr[0]
的高位(第 7 位),这些乘法会溢出 32 位 int
。那么程序的行为不是C标准定义的。
为避免这种情况,值应转换为 uint32_t
。 (这只是为了让算术正确;我没有断言拆开 inet_addr
返回的 in_addr_t
并以这种方式重新组合它的有用性。)
我怀疑那是Arduino代码:)
uint32_t Dot2LongIP(char* ipstring)
{
uint32_t ip = inet_addr(ipstring);
return return nothl(ip);
}
或者如果您不想使用 htonl
uint32_t Dot2LongIP(char* ipstring)
{
uint32_t ip = inet_addr(ipstring);
ip = ((ip & 0xff000000) >> 24) | ((ip & 0x00ff0000) >> 8) |
((ip & 0x0000ff00) << 8) | ((ip & 0x000000ff) << 24);
return ip;
}