了解使用char * cast将Strlen应用于int数组

yr9zkbsy  于 2023-02-21  发布在  其他
关注(0)|答案(3)|浏览(106)

我现在正纠结于这个问题。
我有下面的代码:

int v[10] = {-1, 1000, 2};
    
    int a;
    
    a = strlen((char *)v+1);
    
    printf("strlen result for (char *) v+1: %d\n", a);

我不明白为什么在小端“机器”上的最终结果总是5。根据strlen文档,在这种情况下的char * 类型转换应该返回4。
我也试过在在线编译器和其他机器上,但结果是一样的。我错过了什么?

5jdjgkvh

5jdjgkvh1#

V中的字节最有可能表示为:

0xff, 0xff, 0xff, 0xff, 0xe8, 0x03, 0x00, 0x00,  ...

所以跳过第一个字节(不是第一个int,因为您转换为char *)后,在第一个'\0'字符之前还有5个字节。

wztqucjr

wztqucjr2#

你不应该在int数组上使用strlen。函数的名字已经表明它只应该在合法格式的C字符串上使用。
也就是说,出于学习的原因,数组v的内存布局在little-endian机器上看起来如下所示:

ff ff ff ff e8 03 00 00 02 00 00 00 (00 onwards)
low 0>-^^----<0 1>-------<1 2>-------<2 3> ...----<9 high

由于调用的是strlen((char *)v + 1),计算从^标记的位置开始,有5个非零元素(ff,ff,ff,e8,03),所以结果是5,而不是4,记住1000 == 0x 3e 8。

0md85ypi

0md85ypi3#

这个小演示可以帮助你弄清楚字节在little-endian机器中是如何排序的(假设每件事都像上面写的那样):

char* z = (char*)v + 1;
for (int i = 0; i < 10; i++)
    printf("%02x ", (uint8_t)z[i]);

打印输出应如下所示:ff ff ff e8 03 00 00 02 00 00(就像上面的哈兰Wei展示的那样)。
这个小片段也可以帮助你看到字节是如何存储在big-endian机器中的,所以仅仅计算应该给予5而不是strlen(...)想要说的4。

相关问题