【问题标题】:Why is not ampersand needed in the following code?为什么以下代码中不需要 & 号?
【发布时间】:2019-12-10 14:47:47
【问题描述】:

我了解在 C 编程中,'scanf' 与 '&' 一起用于除字符串之外的所有变量类型(int、float、char、..)。这是我的程序代码。在'scanf'前面,为什么不需要'&'?我可以了解更多有关 scanf 的信息吗?

#include <stdio.h>
#define M 10

int main()
{
    int i, n, sum = 0;
    int a[M];

    do{
        printf("Input a positive number less than %d \n",M);
        scanf("%d", &n);
    }while (!(n >0 && n < M));

    printf("Input %d numbers \n",n);

    for(i=0; i<n ; i++){
        scanf("%d",(a+i));
        sum += *(a+i);
    }

    printf("Sum = %d \n",sum);
}

【问题讨论】:

  • a + i 是一个地址; *(a + i) 是一个值。如果你想使用&amp;,你可以这样做:scanf("%d",&amp;a[i]);,我想大多数人会更喜欢。
  • a 是一个数组...scanf("%d",(a+i));scanf("%d",&amp;a[i]);...顺便说一句,您应该先学习c,然后才能开始思考类似我明白在C 编程中, 'scanf' 与 '&' 一起用于所有变量类型(int、float、char、..)
  • @FiddlingBits Beauty 在旁观者的眼中,但我永远无法理解为什么一个人会取消引用一个指针来获取一个对象 (a[i]) 只是为了让一个人可以获得指向刚刚通过取消引用该指针获得的对象。 &amp;a[i]&amp;(*(a+i)),这显然是无意义的。
  • @Peter-ReinstateMonica 最终结果(机器代码)可能是相同的。我认为清晰是最重要的。
  • @FiddlingBits 我认为减少冗余会更清晰。

标签: c pointers scanf


【解决方案1】:

因为您已将a 声明为一个数组,所以使用该变量名称的表达式本身通常会“衰减” ' 指向数组第一个元素的 指针What is array decaying? - 但另请参阅 Eric Postpischil 为例外添加的出色评论)。这类似于使用char[] 字符串,正如您正确指出的那样,在将其作为参数传递给scanf 时,您不需要使用&amp; 运算符。

i 添加到a 数组的这个“基地址”将给出第“i”个元素的地址(即指向的指针)数组。

这是pointer arithmetic in C 上的一个不错的教程,您可能会觉得有用。

【讨论】:

  • 那我为什么要在代码'scanf("%d", &a[i])'处加上'&'呢?
  • (a + i) 将返回i 索引处的元素地址,而a[i] 将返回i 索引处的值。因此,您需要&amp; 来获取值的地址。
  • 数组名本身并不是指向数组第一个元素的指针。数组的名称本身就指定了数组。如果在表达式中使用它,但不是作为sizeof 或一元&amp; 的操作数,那么数组(不是它的名称,技术上)会自动转换为指向其第一个元素的指针。虽然这可能是在表达式中使用数组的大部分情况,但教人们这个关于数组的错误陈述会导致他们犯其他错误,我们在其他 Stack Overflow 问题中反复看到这些错误。请教正确的规则。
  • @EricPostpischil 一个很好的观点,Eric - 感谢您的提出!我已经更新了我的答案以解决(请原谅双关语)这个问题 - 希望你批准。
【解决方案2】:

scanf 通常采用它正在读取的变量的地址。 a 已经是一个地址(一个衰减为指针的数组),i 只是该地址的偏移量。

这相当于scanf("%d", &amp;a[i]);;它做同样的事情。

【讨论】:

    【解决方案3】:

    c 中变量之前使用的&amp; 运算符返回该变量的地址。数组的基数已经是您想要的地址。 a+i 就像您正在做的那样使用指针算法并通过 i 更改数组的基地址

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-19
      • 2012-08-04
      • 2017-06-10
      • 2020-05-03
      • 2017-02-24
      • 1970-01-01
      • 2021-04-10
      • 2014-08-27
      相关资源
      最近更新 更多