单个字符上的Strlen函数行为

这是我的代码:

void func(char c) { char * ptr = &c; size_t len = strlen(ptr); printf("len - %d\n", len); } 

len始终打印为1。

strlen(..)通过在结尾处找到空字符( \0 strlen(..)来确定char数组的长度。 这里ptr仅使用单个字符的地址( c )进行初始化。 c不包含任何空字符。 ptr如何获得长度?

您不能在不指向以null结尾的数组的指针上使用strlen() 。 它调用未定义的行为 。

一旦你的程序击中UB,没有任何保证。

FWIW, strlen()返回一个size_t类型,因此您应该使用%zu格式说明符来打印结果。

代码的行为在两个方面是未定义的 。 它偶然返回1。

  1. strlen通过从给定地址开始工作,并递增该地址直到达到\0 。 这与C标准库模拟字符串的方式一致。 如果你没有拥有起始地址和\0之间的所有内存(作为一个连续的块),则strlen的输入格式不正确。

  2. 由于格式说明符不正确, printf的行为未定义。 将%zu用于size_t

c不包含任何空字符。 ptr如何获得长度?

它没有。 它似乎在测试中给出了正确的答案,因为c地址后面的内存位置恰好包含一个零字节。 此位置未定义为包含零,程序也不允许访问它,因此您不能指望此类代码继续工作。

在C标准的语言中,程序的行为是未定义的 ,这意味着不仅操作的结果不可预测, 整个程序也变得毫无意义。

即使没有考虑未定义的行为,上面的代码也可以停止使用最轻微的更改 – 例如,当您更改体系结构,编译器甚至编译标志时,或者在混合中添加更多function时。 虽然这些代码片段对于了解内部工作原理是如何有用的,但它们绝不应该用在生产代码中。