【问题标题】:Why char* can hold a single char in C?为什么 char* 可以在 C 中保存单个字符?
【发布时间】:2014-03-19 18:28:18
【问题描述】:

这听起来可能太疯狂了,但我只是有一个想法。为什么在 C 中

char *pc = 'H';      // single character
char *ps = "hello";  // a string

两者都有效?我的意思是为什么 char* 可以保存/引用一个字符以及一个以空字符结尾的字符串?

为什么没有为*pc 生成保护子句或编译器错误,因为char* 不包含以空值结尾的字符串?

我在Ideone 中检查过,没有收到任何警告。

【问题讨论】:

  • 我认为char *pc = 'H' 不会像你想的那样。
  • 如果您尝试printf("%s", pc);,可能会发生非常有趣的事情。可能是垃圾输出或崩溃。
  • 听取您的警告或提高您的警告级别。
  • 始终使用:g++ -Wall。它将帮助您发现运行时错误,例如您的代码可能导致的错误...

标签: c string pointers


【解决方案1】:

可以持有char,因为存在从charchar *的隐式转换(通过int),并且因为sizeof(char *) >= sizeof(char)。不过,您不应该这样做(从技术上讲,这是未定义的行为,因为字符的文字数值不太可能是指向char 类型的有效指针地址)。

在许多/大多数编译器中,这确实会生成警告:

$ gcc -otest test.c
test.c:5: warning: initialization makes pointer from integer without a cast

【讨论】:

    【解决方案2】:
    char *pc = 'H';
    

    上面的语句定义了char *类型的pc,这意味着它可以保存char类型的对象的地址。您正在使用字符 H 对其进行初始化 - 一种不同的类型。请记住,字符文字的类型为int,并计算为其字符代码,在ASCII 中为72。所以,上面的语句等价于

    char *pc = 72;
    

    这是一个非法操作,编译器应该警告你(在 gcc 中,使用标志 -Wall)。您不应该直接将地址分配给指针,因为您不知道是否可以访问内存地址。您应该使用address of 运算符& 来获取对象的地址,然后将其分配给指针。

    char *ps = "hello"; 
    

    在上面的语句中,字符串文字的计算结果是指向其第一个元素的指针。这个地址分配给ps,它的类型相同,即char *。但是,字符串文字在C 中是只读的,但不是const 限定的(与C++ 不同),因此尝试使用指针ps 修改字符串文字不会导致编译器错误,而是导致未定义的行为和最有可能由于段错误导致程序崩溃。因此,您应该将 ps 定义为指向 const object 的指针 -

    const char *ps = "hello";
    

    【讨论】:

      【解决方案3】:

      char *pc = 'H';
      

      'H' 作为int 将被转换为char * 并将用于初始化pc,编译器应该对此给出警告。

      char *ps = "hello";
      

      "hello" 将评估为它的基地址,该地址将用于初始化ps

      【讨论】:

        【解决方案4】:

        当我使用 g++ 编译上述代码行时,我收到以下警告:

        test-12.c:1:12:警告:初始化使指针从整数而不进行强制转换 [默认启用]

        编译器正在执行一些自动转换来初始化pc

        char -> int -> char*.

        只需注意编译器警告,即可检测到您正在尝试的异常操作。

        【讨论】:

          猜你喜欢
          • 2013-11-25
          • 1970-01-01
          • 1970-01-01
          • 2013-11-18
          • 1970-01-01
          • 1970-01-01
          • 2018-07-15
          • 1970-01-01
          • 2016-04-13
          相关资源
          最近更新 更多