【问题标题】:Why the element and not the base address got printed?为什么打印元素而不是基地址?
【发布时间】:2016-02-12 21:53:35
【问题描述】:

这是我写的程序:

main()
{
    struct book
           {
               char name[25] ;
               char author[25] ;
               int callno ;
           } ;

     struct book b1 = { "Let us C", "YPK", 101 };
     display(b1.name, b1.author, b1.callno);
 }

void display(char *s, char *t, int n)
{
    printf ("\n%s %s %d", s, t, n);
}

输出是

让我们 C YPK 101

根据需要

现在我们传递给函数display() 的是字符串nameauthor 的基地址,并且在函数的定义中使用指针。那么为什么函数像printf("\n%s %s %d", s, t, n) 而不是printf("\n%s %s %d", *s, *t, n)

第二个没有运行。 s 不是基地址,*s 不是存储在该地址的字符串吗?

【问题讨论】:

  • main() 应该是int main(void),并且您需要在顶部使用#include <stdio.h>

标签: c string pointers


【解决方案1】:

在 C 中,字符串只是内存块,它们的末尾恰好有一个空终止符。约定是通过指向字符串开头地址的char* 指针来引用字符串。因此,库 printf 函数的设计使得 %s 说明符期望您提供指向最终应打印出的字符串开头的指针。

如果您取消引用 char* 指针,您将返回一个表示该字符串初始元素的 char。请注意,这不是字符串本身——它只是第一个字符。如果您尝试将*s 传递给printf,其中需要%s 说明符,您可能会导致程序崩溃,因为printf 将跳转到其数值由char 并尝试开始打印它在那里找到的字符。

【讨论】:

    【解决方案2】:

    printf() 中的 "%s" 说明符需要一个指向字符串的指针,字符串只是一个以特殊值结尾的字节数组 '\0'printf() 需要 基地址 这样的数组,它还期望 '\0' 位于末尾,否则它将表现不正确。您将包含地址的指针传递给数组所在的内存块的开头,"%s" 说明符将使printf() 从数组中读取并将其内容输出到stdout

    *s 传递给"%s" 是未定义的行为,因为它会将字符值s[0] 解释为地址并尝试从那里读取字符。

    注意 1main() 应该返回 int,所以它应该是其中之一

    int main(void);
    int main(int argc, char *argv[]);
    

    注意2:不要将行尾放在行首,这叫做行尾'\n'有一个原因,这个原因是 stdoutline 缓冲的,所以它需要一个 '\n' 来刷新缓冲区或一个显式的 fflush(stdout)。我不知道如果要结束行,在行首添加'\n' 是否自然,在 它甚至被称为std::endl 并且取决于平台。

    【讨论】:

      【解决方案3】:

      除此之外,C 没有字符串的概念:指向一系列字符(指向第一个字符)的指针。因此,如果您执行 *a 您将获得第一个字符,而不是“字符串”。所有处理所谓字符串的 C 函数都期望这种指针。

      【讨论】:

      • 字符串不是指针。根据定义,string 是“由第一个空字符终止并包括第一个空字符的连续字符序列”。 指向字符串的指针是“指向其初始(最低地址)字符的指针”。
      • @keiththompson:我正在尝试使用可以帮助初学者理解主题的语言,这对他们来说是出了名的困难。我什至引用了“字符串”这个词。
      • 如果你想让初学者理解这个主题,不要告诉他们字符串是指针。他们不是。字符串是一个字符序列;指向字符串的指针指向该字符序列。这并不比字符串是指针的概念更难理解——而且它具有正确的优点。
      • @KeithThompson 查看任何strXXX() 函数的手册页。例如。 strcmp()strcmp() 函数比较两个字符串 s1 和 s2。 它没有说“s1 和 s2 指向的两个字符串”
      • @Barmar:Linux 手册页不精确——我会说不正确。 C 标准规定“strcmp 函数将 s1 指向的字符串与 s2 指向的字符串进行比较。 " (N1570 7.24.4.2p2) Solaris 9 手册页做到了这一点。
      猜你喜欢
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 2020-01-09
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多