Why can I pass a vector of char to the scanf as an address or a direct variable?

2

If the vector name or array is already the address of the first element, why in scanf() , using the primitive types ( int , char , float , double ) I need to pass the address, and when we want to read a string ( "%s" ) do not need? And another, why when we read strings with scanf() , even using & , does it compile?

    
asked by anonymous 02.11.2017 / 15:46

2 answers

1
  

There are conceptual errors in my answer. I only noticed after @Maniero's answer . But I could not remove it, it was already marked as accepted.

     

So while I do not correct / remove this response, please refer to the response for something correct and more accurate.

  

If the name of the array or array is already the address of the first element, why in scanf, using the primitive types (int, char, float, double) I need to pass the

You're talking about int abc[5]; scanf("%d", &abc[0]); , right?

When you do abc , you are getting the memory address of the first element. When you do [n] , you "jump" n houses and get the value contained in the n box.

For example:

 (intA) (intB) (intC) (intD) (intE)
 [----] [----] [----] [----] [----]
 0      1      2      3      4

If you by abc[0] , you will get the value contained in intA .

By% with%, you get the address that points to &abc[0] .

  

When you want to read a string ( intA ) do not need?

The string reading of "%s" will take what was typed and put in the last memory address. When using strings with static allocation, we have a character vector. The usage is like this:

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

Here, each character will be placed in the corresponding position. For example, the word scanf :

(chrA) (chrB) (chrC) (chrD) (chrE)
 [----] [----] [----] [----] [----]
 0      1      2      3      4
[a]    [b]    [c]    [
char palavra[100];
char *ptr;
char **endereco;

ptr = palavra;
endereco = &ptr;
]

The "abc" character is in position 0 of the a , palavra vector in position 1 and b in position 2. The character in position 3 is the string terminated, the null character c .

This is how scanf works. It fills in the positions pointed to by the argument.

  

And another, why when we read strings with scanf , even using & , does it compile?

Because C has poor typing. Very weak.

For example:

 (intA) (intB) (intC) (intD) (intE)
 [----] [----] [----] [----] [----]
 0      1      2      3      4

palavra is a vector, a kind of "special constant pointer" in C. Already ptr is a traditional pointer in C. So the assignment ptr = palavra is respecting all typos.

endereco , in turn, is another pointer. A pointer to a pointer. So it makes sense to assign endereco = &ptr makes sense and respects typing.

However, the C language can not differentiate runtime in time from the variable types. And at compilation level C treats pointers as pointers, regardless of which type pointed to. Of course, the compiler will complain, issue warnings, but if you had it done that way, you know.

C do not worry if you shoot your own foot. Language assumes that the programmer knows what he is doing, so he will not offer him any security against his own mistakes. If you are making a macacada, that of the philosophy of language accept its macacada as law.

    
02.11.2017 / 16:22
6

The answer is already in the question.

If you are using a vector you have an address, and this is what scanf() expects, an address where it should put the value entered. A string is a vector.

If you are using a primitive type it has the value and not the address, then use the & operator. to get his address and indicate to scanf() where he should put the value.

When passing a &string you are getting the address of the variable txt which is the same value that txt is referencing if it is a array in stack . If it is allocated in the heap will give problem, as can be seen in this code:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char txt[10];
    printf("%p\n", txt); //endereço do array
    printf("%p\n", &txt); //é a mesma coisa, por isso funciona
    scanf("%s", &txt);
    printf("%s\n\n", txt);
    char *txt2 = malloc(10);
    printf("%p\n", txt2); //aqui pega o local de armazenamento
    printf("%p\n", &txt2); //aqui pega o endereço da variável
    scanf("%s", &txt2);
//  printf("%s", txt2);  //quebra
}

See running on ideone . And in Coding Ground . Also I put it in GitHub for future reference .

When he has a pointer to the heap , the variable, which is in the stack , stores the value of it, / em>.

When it has an array in the stack it is already the location of the store and variable refers to this location. When something expects a pointer and you pass the variable from an array the pointer to the storage location in the stack is already passed. If you use & it gets the address of this location, which is the same thing.

It's not that it works because it's a weak typing, this is not affecting anything. Even if it were for this I would probably compile, but it would not work. It works because it's the same thing.

Of course the language specification does not say anything about it. It's not that it's guaranteed to be this way, but all implementations I know of have this behavior because it makes sense. The ideal is not to do as it is not in the language specification that is allowed, so one day some implementation may change, although unlikely.

Perhaps the question would be because you do not know that the array is transformed into a pointer when you make some access to your variable .

Depending on the compiler does not compile since it identifies that there is something wrong in what you want to do. Even if access is allowed strictly speaking it should not use this way. This is an extension, not an obligation of the language.

    
02.11.2017 / 16:23