0

My teacher told us to use "&" in order to store values to our desired variables however, I tried to use scanf() and I tried to store values to some variables without the "&" and I noticed that it still works just fine? Is it affecting my code in anyway despite me thinking that it didn't?

Here are the codes that I have tried. The code is a part for checking whether the second input is a substring. The original form which is taught by my teacher:

int main(){
    char word1[100], word2[100];
    int length1, length2;

    printf("Enter the a word: \n");
    scanf("%s", &word1);
    printf("Enter the potetial substring: \n");
    scanf("%s", &word2);

    for(length1=0; word1[length1]!='\0'; length1++);
    for(length2=0; word2[length2]!='\0'; length2++);

    if (length1<length2)
    {
        printf("Second input is not a substring.\n");
    }

Then I tweaked the part where the program asks for inputs to this:

printf("Enter the a word: \n");
scanf("%s", word1);
printf("Enter the potetial substring: \n");
scanf("%s", word2);

I still got the same output even if I removed "&". Hopefully someone can explain if this change is affecting my codes in some way that I may not be aware of, thank you.

5 Answers5

4

C arrays express under evaluation contexts (such as your argument passing to scanf) as a pointer-to-type, where the type is the underlying element type of the array. Therefore word expresses as char*. The address result is that of the first element.

Whereas, &word1 evaluates as the same address, but typed to char (*)[100] (because that's exactly what you asked for). It's the same address, and therefore scanf against a %s specifier will still "work" (term used loosely).

Your compiler should have puked a warning telling you the expected argument type was char* and you're giving char(*)[100]. If it didn't, turn up your warnings.

Summary; The proper syntax for %s is to pass a char*. In this case, that is obtained by word1 (rinse/repeat for word2). It can work using the address-of operator, but there is no reason to use it in this context, and every reason not to.

WhozCraig
  • 59,130
  • 9
  • 69
  • 128
2

scanf needs to know the memory location where to place the read and possibly converted value.

For an elementary type, such as int, double, char it means to pass it the address of the variable.

That is also true for an array of characters, however, the compiler by default uses the address of the first element of an array when you pass the name of the array. So:

int i;
char word[100];

scanf("%d", &i);
scanf("%s", word);
Paul Ogilvie
  • 24,146
  • 4
  • 18
  • 39
  • If you want to deeply understand, there are many posts on stackoverflow. Do a search with "array decaying" and "array address". For example https://stackoverflow.com/questions/8106132/array-addressing and https://stackoverflow.com/questions/1461432/what-is-array-decaying (and all the related post). – Stef1611 Jan 13 '19 at 09:26
  • @HaxCkzersssxz If you figured it out, click on the green tick on the left of this answer to mark your problem as solved. – HolyBlackCat Jan 13 '19 at 09:45
1

Specifically when using scanf to read a string into char [N] (or char *), you must not use &.

Thus the correct way is:

char word1[100]
scanf("%s", word1);

If you teacher says you need & in this case, they're wrong.


%s expects an argument of type char *.

When you pass a char array (char [N]) to it without using &, it's implicitly converted to a pointer to its' first element - char *.

But if you use &, you end up passing char (*)[N] (a pointer to a char array of size N) instead.
This changes the type of a pointer, but not its' numerical value. Because of that, adding & usually has no effect in this case. But formally, since the type of the argumentis is incorrect, the behavior is undefiend.

HolyBlackCat
  • 45,832
  • 5
  • 81
  • 134
1

The & sign is used for pointer referencing. Let's imagine you have the following variable:

int i = 1234;

If you want to get the value of the variable i you would just type the variable name i:

int j = i * 2;

But sometimes you don't want to get the value, but you want get the reference. With the reference you can later change the value of this variable. So you would need a pointer (the address of the variable). Therefore the & sign is used:

int* ptrToI = &i;

Now you could deference the variable (for changing the value) with the help of the * sign:

*ptrToI = 5678;

If you would check the value of the variable i now, you would get the value 5678, because the variable i was changed throw the pointer ptrToI.

The reason why your code is working with an without the & sign is, that word1 and word2 are arrays. And the arrays are always passed as reference. For a simple test you could to the following:

char word1[100];
printf("%08X\r\n", word1);
printf("%08X", &word1);

The printf should output the address of the variable word1. But as you can see the two outputs are the same. That's why your scanf call works with and without the & sign.

Benjamin J.
  • 1,110
  • 1
  • 11
  • 22
0

If you go to the Wikipedia page for scanf you can read :

No matter what the datatype the programmer wants the program to read, the arguments (such as &n above) must be pointers pointing to memory. Otherwise, the function will not perform correctly because it will be attempting to overwrite the wrong sections of memory, rather than pointing to the memory location of the variable you are attempting to get input for.

https://en.m.wikipedia.org/wiki/Scanf_format_string

I don't know which country you are from but try to always look at Wikipedia both in your mothertongue and in english. There is often more informations in english pages (but not always)

Aweuzegaga
  • 186
  • 2
  • 11
  • Thank you, I realized it now since I tried to run a code with int values and the programs stops. Turns out that I really need to use the '&' despite the fact that it still words for the char data type. Thank you. – HaxCkzersssxz Jan 13 '19 at 09:15
  • @HaxCkzersssxz In your case you end up passing a pointer regardless of whether you use `&` or not, so the quote doesn't apply. Not to mention that Wikipedia is not that reliable in some cases. – HolyBlackCat Jan 13 '19 at 09:18
  • @HolyBlackCat it is what Wikipedia explains in the paragraph following the one I quoted but I was not going to copy paste the whole page. About Wikipedia I never encountered an error in a "technical" page yet. I do think it is heavily reliable for these kind of questions. – Aweuzegaga Jan 13 '19 at 09:28