tags:

views:

264

answers:

9

Hello.

When do I need to insert/don't insert & for scanf() in C? Thank you.

int main()
{
    char s1[81], s2[81], s3[81];

    scanf("%s%s%s", s1, s2, s3);

    // If replace scanf() with the expression below, it works too.
    // scanf("%s%s%s", &s1, &s2, &s3);

    printf("\ns1 = %s\ns2 = %s\ns3 = %s", s1, s2, s3);

    return 0;
}

//programming is fun
//
//s1 = programming
//s2 = is
//s3 = fun
+1  A: 

Just a guess, but I'd assume it's because s1, s2, and s3 are arrays.

icktoofay
+7  A: 

scanf puts the scanned values in the address pointed by it's arguments. The & is the address operator, and it's used to take the address of a variable.

But, you are using arrays, and arrays are downgrade to pointers when used as functions arguments. So, you don't need to use the & operator in the case of arrays.

Example:

char s[81];
int n;
int* nptr;
//Initialize nptr to some meaningful value
scanf("%s %d %d",s,&n,nptr);

In this case, we need to use the & operator to get the address were n is kept. We don't need to use it with nptr, because it is already a pointer to someplace in the memory, neither with s, because an array gets downgrade to a pointer when it's passed to a function.

cake
@All. Thank you.
Nano HE
+5  A: 

The arguments after the format specifier must be pointers. When an array name is passed to a function, the location of the initial element is passed, so you don't need to use the & at all in your example. You could do this though (from K&R):

int day, year;
char monthname[20];

scanf("%d %s %d", &day, monthname, &year);

Since day and year are int, you must use the & to get the address of those variables. Since monthname is an array, no & is required.

Bill the Lizard
atlpeg
An array name is not a pointer but is implicitly converted to one depending on the context it is used in. Otherwise `sizeof` and the address-of-operator wouldn't work as expected.
Georg Fritzsche
@Georg: That's true. I edited my answer to be more explicit.
Bill the Lizard
+2  A: 

s1 returns the address of the first element of the array, while &s1 returns the address of the array itself. The address of the first element and the address of the array itself are identical, hence why both representations work.

Blair Holloway
A: 

Generally, you would use scanf the way you do in your uncommented line. The way C arrays work, is the name of arrays like s1, s2, and s3 is actually the address of the first element of the array. For any primitives though, you would have to use the &variable syntax. For example:

float f;
scanf("%f", &f);
Greg Charles
Array names are not pointers to the first element, see the comment on Bills answer.
Georg Fritzsche
+1  A: 

If a is an array, both a and &a result in a pointer in this context:

  • a does due to the array decaying to a pointer (C99, §6.3.2.1/3):

    Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.

    ... emphasis added

  • &a does as a result of the & operator - it returns a pointer to the object.

Georg Fritzsche
+3  A: 

In C, when you are dealing with arrays:

int c_array[24];
c_array == &c_array == &c_array[0]

Yeah, its funny - they look the same (the difference is in the types). Read this.

Sudhanshu
+1  A: 
GG
+3  A: 

From the comp.lang.c FAQ: I thought you always needed an & on each variable passed to scanf.

I highly recommend reading the rest of the comp.lang.c FAQ.

jamesdlin