【问题标题】:why printf doesn't accept a pointer as an argument为什么 printf 不接受指针作为参数
【发布时间】:2020-06-22 04:50:43
【问题描述】:

为什么当我尝试运行此代码时代码块会崩溃:

#include <stdio.h>
#include <stdlib.h>

void main(void)
{
    char *ch= "Sam smith";
    printf("%s\n",*ch);
}

但是当我在 printf 中删除 *ch 并用这样的 ch 替换它时它工作正常

void main(void)
{
    char *ch= "Sam smith";
    printf("%s\n",ch);
}

不应该*ch表示ch指向的地址的内容,即字符串本身,ch表示字符串中第一个元素的地址?所以我的预期正好相反!

我在 windows 8.1 上使用代码块 17.12,gcc 版本 5.1.0。

【问题讨论】:

  • 改用"%c\n"
  • %c 只会打印一个字符
  • *ch 不是指针,它是字符串中的第一个元素,单个字符。
  • 如果只提供1个字符,为什么要打印更多? printf 怎么会知道有一个字符串要打印更多字符?
  • 您似乎忘记启用一组好的警告。对于 GCC,我建议至少 -Wall -Wextra;还可以考虑-Wpedantic -Warray-bounds 来识别其他一些常见错误。

标签: c string pointers printf


【解决方案1】:

*ch dereferences 指针以产生它指向的数据。这里是字符串的第一个字符。

printf 提供错误的说明符是未定义的行为(传递printf 需要指针的值)

printf("%c\n",*c);

将打印第一个字符,而不会崩溃。如果要使用%c(或使用putchar)打印所有字符串,请循环字符。但这就是 %s 所做的。

附带说明,最好使用const 来引用文字字符串,以免尝试修改它们:

const char *ch= "Sam smith";

【讨论】:

    【解决方案2】:

    为什么当我尝试运行此代码时代码块会崩溃:

    char *ch= "Sam smith";
    printf("%s\n",*ch);
    

    ch 的类型为 char *

    %s 转换说明符需要 char *

    你传递*ch,这是取消引用 ch,即char类型。

    如果转换说明符与参数的类型不匹配,就会发生不好的事情(未定义的行为)。

    *ch不应该是指ch指向的地址的内容,即字符串本身

    C 中没有数据类型“字符串”,因此没有“指向字符串的指针”。

    在 C 语言中,“字符串”是一个字符数组,或指向字符数组的指针,带有一个空字节终止符。

    ch 是一个char *,一个指向该数组第一个字符的指针——可以说是一个字符串。

    *chchar,该数组的第一个字符。

    【讨论】:

      【解决方案3】:

      在 C 中,当您想使用指针指向的整个字符串时,您不会取消引用指向字符串的指针。此取消引用过程将导致相应字符串的第一个字符,这不是您想要的。

      此外,如果转换说明符与相对参数的类型不匹配,则为 undefined behavior


      因此,

      printf("%s\n",*ch);
      

      错了。 *ch 是字符串中的第一个字符,在本例中为 S,类型为 char,但 %s 转换说明符需要一个类型为 *char 的参数。

      printf("%s\n",ch);
      

      是正确的。 ch 属于 *char 类型,这是转换说明符 %s 所要求的。

      因此,代码块“崩溃”显然是因为参数类型不匹配。

      【讨论】:

        猜你喜欢
        • 2021-10-29
        • 2015-12-05
        • 1970-01-01
        • 2015-12-15
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        • 2012-10-01
        相关资源
        最近更新 更多