【问题标题】:What is the output of the following code in C? [closed]以下 C 代码的输出是什么? [关闭]
【发布时间】:2018-08-18 14:50:15
【问题描述】:

请看一下这段代码。

 #include <stdio.h>

int main()
{
    char *p;
    p = "%d";
    p++;
    p++;
    printf(p-2,23);
    return 0;
}

我有以下问题

1) 指向字符数据类型的指针如何保存字符串数据类型? 2) 当 p 增加两次时会发生什么? 3)printf()在没有明显引号的情况下如何打印字符串?

【问题讨论】:

  • 指针不保存数据。它保存数据的地址。
  • 您需要了解什么是 C“字符串”。找你的老师或者 - 更好地 - 阅读你的 C 教科书。

标签: c string pointers character


【解决方案1】:

“指向字符数据类型的指针如何能够保存字符串数据类型?”好吧,在 C 语言中,键入 'pointer to char' is 是字符串类型,这在一定程度上是正确的。任何对字符串(包括printf)进行操作的函数都会通过char * 类型的参数来接受这些字符串。

"printf() 如何在不使用明显引号的情况下打印字符串?"没有规则说你需要引号才能有一个字符串!带引号的那个东西是 string constantstring literal,这是将字符串放入程序的一种方法,但它根本不是唯一的方法。有很多方法可以构造(以及操作和修改)根本不涉及任何引号的字符串。

让我们画一些代表你的代码的图片:

char *p;

p 是指向char 的指针,但正如您正确指出的那样,它还没有指向任何地方。我们可以像这样用图形表示它:

   +-----------+
p: |    ???    |
   +-----------+

接下来将p 设置为指向某处:

p = "%d";

这会将字符串 "%d" 分配到某处(无论在哪里),并设置 p 指向它:

   +---+---+---+
   | % | d |\0 |
   +---+---+---+
     ^
     |
      \
       \
        \
         |
   +-----|-----+
p: |     *     |
   +-----------+

接下来,您开始递增p

p++;

正如你所说,这使得p 指向过去的位置,指向字符串的第二个字符:

   +---+---+---+
   | % | d |\0 |
   +---+---+---+
         ^
         |
         |
         |
         |
         |
   +-----|-----+
p: |     *     |
   +-----------+

接下来,

p++;

现在我们有了:

   +---+---+---+
   | % | d |\0 |
   +---+---+---+
             ^
             |
            /
           /
          /
         |
   +-----|-----+
p: |     *     |
   +-----------+

接下来你打电话给printf,但有点奇怪:

printf(p-2,23);

关键是表达式p-2。如果p指向字符串中的第三个字符,那么p-2指向字符串中的第一个字符:

         +---+---+---+
         | % | d |\0 |
         +---+---+---+
           ^       ^
      +----|----+  |
 p-2: |    *    | /
      +---------+/
                /
               |
         +-----|-----+
      p: |     *     |
         +-----------+

而那个指针p-2 或多或少与printf 收到的指针相同,如果您更习惯地称为printf("%d", 23)

现在,如果您认为 printf 收到了一个字符串,那么您可能会惊讶地听到 printf 很高兴收到一个 char * 而实际上它总是收到一个char *。如果这令人惊讶,问问你自己,如果不是指向char 的指针,你让printf 收到了什么?

严格来说,C 中的字符串是一个字符数组(以'\0' 字符结尾)。但是有一个关于 C 的超级重要的秘密事实,如果你还没有遇到过,你很快就会发现(因为它根本不是秘密):

在 C 中你不能用数组做很多事情。每当你在 C 中的表达式中提到一个数组,每当你看起来想对数组的值做一些事情时,你得到的是一个指向数组的第一个元素。

该指针几乎就是数组的“值”。由于指针算法的工作方式,您可以使用指针非常透明地访问数组(几乎就像指针 数组一样,但当然不是)。这一切都非常适用于字符数组(和指针)。

所以由于 C 中的字符串是一个字符数组,所以当你编写时

"%d"

这是一个由三个字符组成的数组。但是当你在表达式中使用它时,你得到的是一个指向数组第一个元素的指针。例如,如果你写

printf("%d", 23);

你有一个字符数组,你在一个表达式中提到它,所以你得到的是一个指向数组第一个元素的指针,这就是传递给printf的东西。

如果我们说

char *p = "%d";
printf(p, 23);

我们做了同样的事情,只是更明确一点:再一次,我们在表达式中提到了数组"%d",所以我们得到的值是指向它的第一个元素的指针,所以这就是用于初始化指针变量p 的指针,这是作为第一个参数传递给printf 的指针,所以printf 很高兴。

在上面,我说过“在 C 语言中,'pointer to char' 类型是字符串类型,这在一定程度上是正确的”。后来我说“C 中的字符串是字符数组”。那么它是哪一个?数组还是指针?严格来说,字符串是一个字符数组。但是像所有数组一样,我们不能对字符数组做很多事情,当我们尝试时,我们得到的是指向第一个元素的指针。所以大多数时候,C 中的字符串是通过指向字符的指针来访问、操作和修改的。所有对字符串进行操作的函数(包括printf)实际上都会接收指向char 的指针,指向它们将要操作的字符串。

【讨论】:

  • 感谢@Steve Summit 的清晰解释。尽管对这个问题投了反对票,但我学到了一些新东西。
【解决方案2】:

下面解释了发布代码中的每个语句:

 #include <stdio.h>// include the header file that has the prototype for 'printf()'

int main( void )   // correct signature of 'main' function
{
    char *p;       // declare a pointer to char, do not initialize
    p = "%d";      // assign address of string to pointer
    p++;           // increment pointer (so points to second char in string
    p++;           // increment pointer (so points to third char in string
    printf(p-2,23);// use string as 'format string' in print statement, 
                   // and pass a parameter of 23
    return 0;      // exit the program, returning 0 to the OS
}

【讨论】:

  • 感谢@user3629249 逐行解释此代码。
【解决方案3】:

1) 指向字符数据类型的指针如何能容纳字符串数据类型?

Ans:String 不是 C 中的基本数据类型。String 只不过是 char 在内存中的连续放置,直到遇到 '\0'。

2) 当 p 增加两次时会发生什么?

Ans:它现在指向 '\0' 字符。

3) printf()如何在不使用明显引号的情况下打印字符串

Ans:字符串总是用引号表示,因此不需要额外的引号。

【讨论】:

  • 感谢@Sandeep 的回答!
【解决方案4】:

1.指向字符数据类型的指针怎么能保存字符串数据类型?

-> Char pointer 将保存char datatype 的地址,因为stringchar datatypes 的集合。因此charpointer 可以保存string 数据类型..

2。当p 增加两次时会发生什么?

-> 当您将char pointer 分配给string 时,指针将指向第一个字符。因此,当您将指针递增两次时,它将保存第 3 个字符的地址,在您的情况下为 '\0';

3。 printf()如何在没有使用明显引号的情况下打印字符串?

-> printf(p-2,23); 在您的情况下使用字符串作为格式标识符,它是"%d"

【讨论】:

  • 感谢@kiran Birandar 发布您的宝贵答案。
猜你喜欢
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多