【问题标题】:Arguments passed to puts function in C传递给 C 中 puts 函数的参数
【发布时间】:2012-09-26 19:45:55
【问题描述】:

我最近才开始学习 C。我在学习数组和指针的概念时,遇到了理解它的绊脚石。

考虑这段代码 -

#include<stdio.h>

int main()

 {

 char string[]="Hello";
 char *ptr;

 ptr=string;

 puts(*ptr);

 return(0);

 }

它可以编译,但在执行时遇到分段错误。

我得到的警告是:

`puts' 的参数 1 中的类型错误;找到 'char' 预期的 'pointer to char'

现在 *ptr 确实返回一个字符“H”,我最初的印象是它只接受一个字符作为输入。

后来,我了解到 puts() 在输入时需要一个指向字符数组的指针,但我的问题是当我传递这样的东西时 - puts("H") 与puts(*ptr),假设 *ptr 确实包含字符“H”。

【问题讨论】:

  • 警告几乎解释了这个问题。您正在将单个 char 传递给需要指向 char 的指针的函数。
  • 在C语言中,char和长度为1的字符串是不一样的,把char看成一个小数比较好。

标签: c puts


【解决方案1】:

"H" 是一个字符串文字,由 2 个字节 'H''\0' 组成。每当您的代码中有“H”时,就意味着指向具有 2 个字节的内存区域的指针。 *ptr 只返回一个 char 变量。

【讨论】:

    【解决方案2】:

    通过执行puts(*str),您将取消引用str 变量。然后,这将尝试使用“H”字符作为内存地址(因为这是str)指向的内存地址,然后是段错误,因为它将是一个无效的指针(因为它可能会落在您的进程内存之外)。这是因为puts 函数接受一个指针作为参数。

    你真正想要的是puts(str)

    顺便说一句,后一个示例puts("h") 在编译时用“h”填充字符串表,并用隐式指针替换那里的定义。

    【讨论】:

    • 您是如何想到获取“H”的地址会“落入您的 BIOS 内存区域”的概念?这个答案有很多混乱(不,给出字符串文字不是扩展名而是普通的C)。
    • @slugonamission:另外,DevSolar 是对的,您只是假设它会落在您的 BIOS 内存区域中。这实际上是不对的,如果我是你,我会删除它。 :)
    • @netcoder - 它来自这样一个事实,即通过取消引用str,您将获得它指向的值,在这种情况下,'H',或者更确切地说,0x48,我 认为它总是映射到您的 BIOS 存储。
    • 至少在 x86 上。当然,基本上在任何其他平台上都是错误的,所以我也删除了它:P
    • 感谢您谈论字符串表和隐式指针。我很困惑为什么在 puts("H"), "H" 中表示指向字符数组的指针。现在分段错误也有意义了。
    【解决方案3】:

    puts() 函数接受一个指向字符串的指针,而您所做的是指定单个字符。

    看看这个Lesson 9: C Strings

    所以与其做

    #include<stdio.h>
    
    int main()
    
     {
    
     char string[]="Hello";
     char *ptr;
    
     ptr=string;    // store address of first character of the char array into char pointer variable ptr
                    // ptr=string is same as ptr=&string[0] since string is an array and an
                    // array variable name is treated like a constant pointer to the first
                    // element of the array in C.
     puts(*ptr);    // get character pointed to by pointer ptr and pass to function puts
                    // *ptr is the same as ptr[0] or string[0] since ptr = &string[0].
     return(0);
    
     }
    

    你应该这样做

    #include<stdio.h>
    
    int main()
    
     {
    
     char string[]="Hello";
     char *ptr;
    
     ptr=string;  // store address of first character of the char array into char pointer variable ptr
    
     puts(ptr);  // pass pointer to the string rather than first character of string.
    
     return(0);
    
     }
    

    【讨论】:

      【解决方案4】:

      当你在gets中输入字符串或想用puts显示它时,你必须实际传递指针或字符串的位置

      例如

      char name[] = "Something";
      

      如果你想打印那个

      你必须写printf("%s",name); --&gt; name actually stores the address of the string "something"

      如果你想显示,可以使用 puts

      puts(name) ----> same as here address is put in the arguments
      

      【讨论】:

        【解决方案5】:

        没有。

        'H' 是字符文字。

        “H”实际上是一个包含两个元素的字符数组,一个是“H”,另一个是终止的“\0”空字节。

        【讨论】:

          【解决方案6】:

          puts 正在等待一个字符串指针作为输入,因此它正在等待一个内存地址。但是在您的示例中,您提供了内存的内容*ptr*ptr 是地址为ptr 的内存内容,即h

          ptr是内存地址

          *ptr是这段内存的内容

          puts的入参是地址类型但是你提供了char类型(地址的内容)

          puts 从您输入的地址开始逐个字符地开始打印,直到包含0 的内存,然后它停止打印

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-27
            • 2018-05-29
            • 2015-01-30
            • 2012-12-02
            相关资源
            最近更新 更多