When should I use ampersand with scanf()

What are the rules for using ampersand in c while using scanf()?

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));
}

Why for String do I not need to use the the ampersand and for int I have to use it?

Is there a rule on when to use the ampersand sign?


Solution 1:

scanf reads particular types of data into addresses which are passed as second, third, fourth and so on arguments.

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

Here var is value and &var is address. The above statement says: read %d (integer) type of data into &var address.

char s[20];
scanf("%s",s);

Here s is address not the value because s is a character array (string). An array name itself indicates its address. s == &s[0], these are both the same.

The above statement says: read %s (array of characters) type of data into address location starting from 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.
    }
}

There is no single format specifier to scan group of integers at a time as like scanning group of characters at time with the help of %s.

And here a=&a[0]; you can scan single integer value directly to the address which is pointed by a.

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

if you enter 10 then prints a[0]=10.

Usage of Pointers:

if you use pointers as shown below, then you will come to know how to increment the pointer and get the values into different locations of array.

You can move the pointer location to read arrays. You can read arrays without moving pointer location.

  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];

This is two dimensional array so you require 5 pointers to scan so I was declared pointer array.

#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");
    }
}

Direct scanning

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  
    }
}

You will found most of the above stuff in The C Programming Language (Second edition) by Brian W. Kernighan and Dennis M. Ritchie.

Solution 2:

Because C strings have a type of char []. The array name has the value of it's address, but an int variable doesn't, you need to use &

And it's wrong to write void main, you should always use int main.