何时应该在scanf()中使用“&”符号?

19
scanf()在C语言中使用&符号的规则是什么?
struct Student 
{
  char name[20];
  int id;
};

int main(void)
{
  struct Student std1;
  printf("enter name and id of std1\n");
  scanf("%s %d", std1.name, &(std1.id));
}

为什么在使用String时我不需要使用&符号,而在使用int时我需要使用它?

有没有关于何时使用&符号的规定?


2
阅读C字符串教程 - Dariusz
2
@PP在他的评论中可能听起来有点居高临下,但他是绝对正确的:首先阅读一本好的C编程书籍。Kernighan&Ritchie的《C程序设计语言》是一个很好的资源。 - SolarBear
2
@PP 绝对正确。在理解为什么一个变量需要 & 而另一个不需要之前,你不能开始编写 C 代码。这就像试图在不知道油门和刹车的区别的情况下开车一样。 - Carey Gregory
3个回答

31

scanf函数可以将特定类型的数据读入作为第二、第三、第四等参数传递的地址中。

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

这里的var是值,&var是地址。上述语句表示:将%d(整数)类型数据读入到&var地址中。
char s[20];
scanf("%s",s);

这里的s是地址而不是值,因为s是字符数组(字符串)。数组名称本身就表示其地址。 s == &s[0],它们是相同的。

上述语句的意思是:从s开始,将%s(字符数组)类型的数据读入地址位置。

#include<stdio.h>
#define MAX 5

int main()
{
    int a[MAX];
    int i;
    printf("Enter Values of array\n");
    for(i=0;i<MAX;i++)
    {
        printf("Enter a[%d] =  ",i);
        scanf("%d",&a[i]); // reading each time single integer value starting index with 0 and ending index MAX-1.
    }
}

没有单一的格式说明符可以一次扫描一组整数,就像用%s一次扫描一组字符那样。

而在这里a=&a[0];,你可以直接将单个整数值扫描到由a指向的地址。

scanf("%d",a);
printf("a[0]=%d\n",a[0]);

如果您输入10,则打印a[0]=10

指针的使用:

如果按照下面所示使用指针,则可以了解如何递增指针并将值放入数组的不同位置。

您可以移动指针位置以读取数组。您可以在不移动指针位置的情况下读取数组。

  1. Reading arrays by moving pointer locations

    #include<stdio.h>
    #define MAX 5
    
    int main()
    {
        int a[MAX];
        int i;
        int *ptr;
        ptr = &a[0];
        printf("Enter Values of array\n");
        for(i=0;i<MAX;i++)
        {
            printf("Enter a[%d] =  ",i);
            scanf("%d",ptr);
            ptr++; //moving pointer 
        }
    }
    
  2. Reading arrays with out moving pointer locations.

    #include<stdio.h>
    #define MAX 5
    
    int main()
    {
        int a[MAX];
        int i;
        int *ptr;
        ptr = &a[0];
        printf("Enter Values of array\n");
        for(i=0;i<MAX;i++)
        {
            printf("Enter a[%d] =  ",i);
            scanf("%d",ptr+i); //we are not moving ptr position we scaning each time into next location by incrementing i 
        }
    }
    

    When a pointer is incremented then the increment is dependent on the type of pointer. Here ptr is an integer pointer so ptr+1 will increment ptr+sizeof(int) locations.

int a[5][5];

这是一个二维数组,所以你需要5个指针来扫描,因此我声明了指针数组。

#include<stdio.h>
#define MAX 5

int main()
{
    int a[MAX][MAX],i,j;
    int *pointer[MAX];

    for(i=0;i<MAX;i++)
        pointer[i]=&a[i][0]; //initializes the pointers 

    printf("Enter elements :\n");
    for(i=0;i< MAX;i++)
    {   
        for(j=0;j<MAX;j++)
        {
            printf("Enter the a[%d][%d] element: ",i,j);
            scanf("%d",pointer[i]+j); //each time you will move like 00 01 02 03 04 and second time 10 11 12 13 14 and so on...
            //printf("%u or %x",pointer[i]+j,pointer[i]+j);//un comment this line and see the addresses how the address incrementing for each element
        }
    }

    printf("The Given Matrix:\n\n");
    for(i=0;i<MAX;i++)
    {
        for(j=0;j<MAX;j++)
        {
            printf("%d",*(pointer[i]+j));
            printf("\t\t");
        }
        printf("\n\n");
    }
}

直接扫描
printf("Enter elements :\n");
for(i=0;i< MAX;i++)
{   
    for(j=0;j<MAX;j++)
    {
        printf("Enter the a[%d][%d] element: ",i,j);
        scanf("%d",&a[i][j]); //we can't do like this a++ or ++a or a+i this is illegal in C. for that purpose we are using pointers  
    }
}

你可以在 Brian W. Kernighan 和 Dennis M. Ritchie 的《C程序设计语言》(第二版) 中找到大部分以上内容。

8

由于C语言字符串类型为char []。数组名称的值为其地址,但是int变量没有地址,因此需要使用&

而且写void main是错误的,你应该始终使用int main


1
在C语言中,字符串是字符数组(以\0字符结尾)。数组名返回数组的第一个元素的指针(存储数组的内存位置),标量变量的名称返回标量的值,因此您需要使用&运算符获取标量的内存位置,以便写入该值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接