【问题标题】:What would be printed?会打印什么?
【发布时间】:2021-04-05 12:42:10
【问题描述】:

你能解释一下为什么下面程序的输出是 1 吗?

const char *str = "mms";

printf("%d\n", strlen(str + 2));

return 0;

如果我加 1,结果是 2。

【问题讨论】:

  • 你学过指针运算吗?这似乎应该成为每个体面的 C 课程/教程的一部分
  • 请注意,strlen(str + 2)strlen(str) + 2 不同。也许这就是你困惑的根源?

标签: c printf c-strings strlen


【解决方案1】:

对于初学者来说这个电话

printf("%d\n", strlen(str + 2));

可以调用未定义的行为,因为根据 C 标准(7.21.6.1 fprintf 函数)

9 如果转换规范无效,则行为是 undefined.275) 如果任何参数不是正确的类型 相应的转换规范,行为未定义。

根据函数strlen的声明,转换说明符d需要int类型的参数,而表达式strlen( str + 2 )的类型为size_t

size_t strlen(const char *s);

你必须写

printf("%zu\n", strlen(str + 2));
        ^^^

你声明了一个指向字符串字面量的指针

const char *str = "mms";

字符串文字在内部被表示为一个字符数组,如

{ 'm', 'm', 's', '\0' }

也就是说它有4个字符,包括终止零字符'\0'

指针str 指向文字的第一个字符。表达式str + 2 指向文字的第三个字符,即由于指针算法而指向字符's'

来自 C 标准(7.23.6.3 strlen 函数)

3 strlen函数返回前面的字符数 终止空字符。

所以表达式str + 2实际上指向字符串"s",那么函数将返回1,并将其输出。

【讨论】:

    【解决方案2】:

    以下说明

     printf("%d\n", strlen(str));
    

    将打印3,因为它是字符串"mms"的长度。

    记住str指向的字符串是这样存储的

    ------------------
    | m | m | s | \0 |
    ------------------
    

    所以str+1是指向字符串第二个元素的指针(相当于&(str[1])str+2指向第三个元素(相当于&(str[2])

    str+2 指向的字符串是什么?它是"s"。所以它的长度是1。


    如果你的目的是在str的长度上加上2,你必须注意括号的使用:

    printf("%d\n", strlen(str)+2);
    

    这样strlen的参数就是str,返回的长度加上2

    【讨论】:

      【解决方案3】:

      好吧,strlen 从您传递的指针开始计数,直到找到 NULL 或 \0 字符。

      所以str+2 指向字母s,所以字符串末尾只有一个字母; str+1 指向 m 等等...你得到 2

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-19
        • 1970-01-01
        • 1970-01-01
        • 2020-01-11
        • 2020-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多