简体   繁体   中英

Passing string to an int variable in C?

This is a program in which a string "6" is passed to an integer variable y

#include<stdio.h>
void main()
{
    int x=0;
    int y=0;
    if(x==1)
        y=20;
    if(x==4)
        y=25;
    if(x==0)
        y="6"+10+x+y;
    printf("y= %d",y);
}

The output of this program is y= 4206638 which means here "6" is equal to 4206628. Can anyone tell me how is "6" equal to 4206628. If i replace "6" with some other character, the output is unaffected.

y="6"+10+x+y;

With this line of code; the address of the string literal "6" is being assigned in memory to the int object i, which is in most cases undefined behavior because the value of a memory location is in many cases beyond the area an object of type int can hold.

This undefined value is then printed by:

printf("y= %d",y);

Moreover, we you would have observed the value won't be same everytime you run the code. The only issue is that when it casts a pointer to an integer, C compilers don't regard it as an error because a pointer (address in memory) is also a number (though in most situations "address number" overflows int) and you can print it in whatever format you want: decimal, hexadecimal, and so on. Also, the compiler must have given you a warning you doing so without an explicit cast; Something like:

warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]

Moral: We shouldn't ignore the warnings given by our smart compiler.

The problem is that you are either using a broken compiler or you are not paying attention to it.

"6" is a string literal in the form of an array placed in read-only memory. This array, like any array, "decays" into a pointer to the first element when used in an expression. So the "6"+10+x+y part is pointer arithmetic (using 1 byte characters), which in turn goes way beyond the end of that array and causes undefined behavior.

Then finally, you try to assign that strange, invalid pointer to an int . This isn't allowed by the C language, see "Pointer from integer/integer from pointer without a cast" issues .

The address will vary between different systems. You can run this well-defined code to see for yourself what's going on:

#include<stdio.h>
#include <stdio.h>
#include <stdint.h>

int main()
{
    int x=0;
    int y=0;

    printf("%p (address of \"6\")\n", (void*)"6");
    printf("+ 0x%x\n", 10+x+y);
    printf("= 0x%x\n", (uintptr_t)"6"+10+x+y);
}

I get this output:

0x402004 (address of "6")
+ 0xa
= 0x40200e

So why didn't the compiler give you an error for this invalid code? The reason: What must a C compiler do when it finds an error?

If you are a beginner learning C, then I strongly recommend that you compile like this (assuming gcc/clang/icc):

gcc -std=c11 -pedantic-errors -Wall -Wextra -Werror

This will block broken C code from resulting in a confusing, incorrect program getting built.

When you define a string literal expression in C, a string is being created as an array in read only memory and a pointer is being passed back to the application. In this case, the variable stored in memory should be an ASCII number 6 followed by a null terminator (ie {0x36, 0x0}). However, in your program, the value used in your expression is actually the memory address for the first element of this array, so seeing a value of 4206638 makes a bit of sense.

If you were looking to use the ASCII value for number 6 (0x36) in your expression, you should use single quotes (ie '6'), which would pass back a signed integer 0x36, which is the ASCII representation of the number 6.

If you are looking to directly convert a string to an integer in C, you could use the standard library function atoi(), which receives a string pointer, such as the pointer returned in your application for string "6", and returns a signed integer.

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