【问题标题】:What is the difference between scanf("%d", *p) and scanf("%d", p)?scanf("%d", *p) 和 scanf("%d", p) 有什么区别?
【发布时间】:2014-05-30 11:50:27
【问题描述】:

指针对我来说是新事物,我正在努力理解它,但我不会屈服并希望学习它。

scanf ("%d", *p) 和 scanf ("%d", p) 之间有什么区别?

在示例中,我看到如果我想在变量中输入一些值,我应该使用scanf ("%d", p)。这对我来说没有意义。不应该是scanf ("%d", *p)吗?

我将其解释为:“在指针指向的地方放置一些整数值”,例如它指向变量x,然后它应该是x = 10,但事实并非如此。那么如何使用scanf() 和指针来设置数组中的值呢?

我在哪里以及哪里做错了?我正在尝试使用 C 语言来学习这一点,因为它是我应该在课堂上使用的语言。

例如:

#include <stdio.h>
int main () {
    float x[10], *p;
    int i;
    p = &x[0];
    for (i = 0; i < 10; i++) {
        scanf("%d", p + i);
    }
    for (i = 0; i < 10; i++) {
        printf("%d", *(p + i));
    }
    return 0;
}

为什么只有p + i 在第一个for () {} 和*(p + i) 在第二个循环?我会将*(p + i) 也放在第一个for () {} 中。 *(p + i) 对我来说就像:“第 (p+i) 个元素是什么并使其等于某个值”。

【问题讨论】:

  • 也许你应该添加类型...
  • 什么是p?如果p 不是指针,则应使用scanf ("%d", &amp;p)
  • 顺便说一句:在使用希望读取的内容之前检查scanf() 的返回值。 scanf("%d", p + i) != 1) Oops();
  • 如果p是一个指针,那么p的值就是“指针指向的地方”。 *p 将是“被指向的东西”。
  • scanf("%d", &amp;x[i]); 会更容易写和理解

标签: c arrays pointers dereference


【解决方案1】:

*p 表示去p 指向的地方
&amp;p 表示取p 的地址,或者“获取指向”p 的指针

int i;
scanf("%d", &i); // gives scanf a pointer to i

int i;
int *p = &i;
scanf("%d", p); // a more contrived way to say the same thing

强制性的视觉解释是Pointer Fun with Binky。

您可以从右到左读取类型:

int *p => "p 的类型为 int *" => p 是指向 int 的指针
int *p => "*p 的类型为 int" = > *p 是p 指向的int

【讨论】:

    【解决方案2】:

    一个是对的,另一个是错的。 (或者两者都可能是错误的,这取决于 p 是什么。)

    如果你打电话

    scanf("%d", SOMETHING);
    

    那么SOMETHING 必须是一个指向int的指针。

    如果您有 int 对象,请使用一元 &amp; 获取其地址(即指向该对象的指针):

    int n;
    scanf("%d", &n);
    

    如果p 恰好是int*,那么你可以使用它的值:

    int *p;
    scanf("%d", p);
    

    但这里我没有为p 赋值,所以它可以编译但有未定义的行为。没关系:

    int n;
    int *p = &n;
    scanf("%d", p);
    

    至于使用*p,只有当p是指向int的指针时才有效:

    int n;
    int *p0 = &n;
    int **p = &p0;
    scanf("%d", *p);
    

    但这样做几乎没有意义。绝大多数情况下,参数只是一些int 对象的地址,例如&amp;n。

    如果n 是一个int,那么仅仅将n 传递给scanf 是没有意义的。您只需传递n 的当前值。关键是您要允许scanf 在n 中存储一个新值,为此,scanf 需要n 的地址。

    【讨论】:

      【解决方案3】:

      C 中的函数调用按值而不是按引用传递参数。这意味着,当您调用带有参数的函数时,该函数会收到 副本 个参数,并且该函数不能直接修改来自调用站点的原始参数。那就是:

      int x = 42;
      foo(x);
      printf("%d\n", x);
      

      foo不能改变变量x,代码会一直打印42。

      但在很多情况下,函数可能想要修改来自调用者的参数。 scanf 就是这样一种情况。为了实现这一点,这些函数需要使用间接层。调用者不是将要修改的变量直接传递给函数,而是传递一个指向该变量的指针。然后该函数接收指针的副本,并通过取消引用它,可以访问和修改它指向的变量。

      我建议花一些时间阅读 comp.lang.c 常见问题解答。这个话题在:

      【讨论】:

        【解决方案4】:

        如果 p 是变量(例如,一个 int),您将使用 &p 将其指针传递给 scanf。 p 单独不是一个指针,*p 使问题更加复杂。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-10
          • 1970-01-01
          • 2019-12-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多