简体   繁体   中英

What happens when I assign a string to an int?

If i were to instantiate an int with a string what does the value of that int actually hold? eg for the following code:

#include <stdio.h>

int main(void) {
    int a = "abcd";
    printf("a as string witn & = %s\n", &a);
    printf("a as int witn no & = %d\n", a);
    printf("a as int witn & = %d\n", &a);
}

I get values that differ with each execution such as:

a as string witn & = "?????W?
a as int witn no & = 130694946
a as int witn & = 1475726188

or

a as string witn & = "?O?Kp\?
a as int witn no & = 55557922
a as int witn & = 1550863212

what are these values? Why are they always different? And what is 'a' actually storing?

int a = "abcd";

This is illegal in C.

Well, sort of. The C standard doesn't actually use the term "illegal" for this kind of thing. To be painfully precise, it's a constraint violation , which means that any conforming compiler must issue a diagnostic message (which might be a non-fatal warning).

The expression "abcd" is an array expression, of type char[5] (4 for the letters plus 1 for the terminating \\0' ). In most contexts, including this one (if it were valid), an array expression is implicitly converted to a pointer to the array's first element. After that conversion, the value is of type char* , and it's a pointer to the 'a' .

There is no implicit conversion from char* to int , which is why this initialization is invalid. You could add a cast, which is an explicit conversion:

int a = (int)"abcd";

This would store in a the memory address of the string, converted from char* to int . On many systems, this conversion, though it's legal, yields garbage; for example, on the system I'm typing this on, a char* is 64 bits and an int is only 32 bits.

Compilers for older versions of the C language (prior to 1989) were more lax about implicit conversions, often allowing integers and pointers to be assigned to each other. More modern compilers, even though they'll diagnose this error if you ask them to, might (or might not) still generate code to perform the implicit conversion. (Strictly speaking the behavior is undefined, but an implicit conversion is common.)

If your compiler rejects

int a = "abcd";

it's doing its job. If it merely warns you about it, it's still doing its job as far as the C standard is concerned, but it's really not doing you any favors by generating that implicit conversion.

Bottom line: The value assigned to a is garbage, and if your compiler doesn't complain about it, find out what options you need to give it to make it do so.

As for the output of your printf calls:

printf("a as string witn & = %s\n", &a);

%s requires a char* argument that points to a string. &a is of type int* , and does not point to a string. The behavior is undefined. Most likely printf will print garbage bytes starting at the beginning of a until it happens to encounter a null byte (or crashes).

Don't do that.

printf("a as int witn no & = %d\n", a);

If your program hasn't already crashed at this point, this prints the value of a . That value is garbage, which might typically be the converted value of the address of the string literal, or just the low-order 32 bits of that address.

printf("a as int witn & = %d\n", &a);

%d requires an argument of type int . &a is of type int* . Undefined behavior. This might print the memory address of a as a decimal integer. Don't do that. If you really want to print the address of a , the correct way to do it is:

printf("&a = %p\n", (void*)&a);

Perhaps the most efficient way to answer the question is to stroll through the question code:

#include <stdio.h>

int main(void) {
    int a = "abcd";

The above line declares an int called a, and initializes a with the address of the string "abcd". This line will cause a compiler to become a little grumpy, in that it will complain something like: warning: initialization makes integer from pointer without a cast .

    printf("a as string witn & = %s\n", &a);

The object of the above line seems to b to print a string. Unfortunately, &a is the memory address of where the variable is stored in memory, which appears it was something like 1550863212 or 0x93E6DF1 on your system. This value is not an ASCII or UTF-8 string; hence it appears to print out garbage: "?????W? , "?O?Kp\\? , or some other nonsense string, depending on what the address of a happens to be. Of course, this line will make the compiler even more grumpy; format '%s' expects type 'char *', but argument 2 has type 'int *'

    printf("a as int witn no & = %d\n", a);

The above line attempts to print the value of a as a signed integer. It will also appear as nonsense, Since the value of a is the address of the string "abcd". Hence, the value of a (as a signed integer) will be the signed integer representation of the address where the string "abcd" is stored in memory.

    printf("a as int witn & = %d\n", &a);

The above line attempts to print the memory address of a as a signed integer. As with the others, this will most likely appear as nonsense again.

    printf("a as a string[%s]\n", a);

For your viewing pleasure, I added the above line, which outputs: " a as a string[abcd] ". This proves that the variable a was successfully initialized, although (again) the compiler thinks us insane: warning: format '%s' expects type 'char *', but argument 2 has type 'int' }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM