简体   繁体   English

将字符串传递给 C 中的 int 变量?

[英]Passing string to an int variable in C?

This is a program in which a string "6" is passed to an integer variable y这是一个程序,其中将字符串“6”传递给 integer 变量 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.该程序的 output 是y= 4206638 ,这意味着这里的“6”等于 4206628。谁能告诉我“6”如何等于 4206628。如果我用其他字符替换“6”,则 output 不受影响。

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. 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.唯一的问题是,当它将指向 integer、C 的指针转换为错误时,编译器不会将其视为错误,因为指针(内存中的地址)也是一个数字(尽管在大多数情况下,“地址号”溢出 int)并且您可以以您想要的任何格式打印:十进制、十六进制等。 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. "6"是一个以数组形式放置在只读 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.所以"6"+10+x+y部分是指针算术(使用 1 字节字符),这反过来又超出了该数组的末尾并导致未定义的行为。

Then finally, you try to assign that strange, invalid pointer to an int .最后,您尝试将那个奇怪的无效指针分配给int This isn't allowed by the C language, see "Pointer from integer/integer from pointer without a cast" issues . C 语言不允许这样做,请参阅“Pointer from integer/integer from pointer without a cast”问题

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:我得到这个 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?原因: C 编译器发现错误时必须做什么?

If you are a beginner learning C, then I strongly recommend that you compile like this (assuming gcc/clang/icc):如果你是初学者学习C,那么我强烈建议你这样编译(假设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.这将阻止损坏的 C 代码导致构建混乱、不正确的程序。

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.当您在 C 中定义字符串文字表达式时,将在只读 memory 中将字符串创建为数组,并将指针传递回应用程序。 In this case, the variable stored in memory should be an ASCII number 6 followed by a null terminator (ie {0x36, 0x0}).在这种情况下,存储在 memory 中的变量应该是一个 ASCII 数字 6,后跟一个 null 终止符(即 {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.但是,在您的程序中,表达式中使用的值实际上是该数组第一个元素的 memory 地址,因此看到 4206638 的值是有道理的。

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.如果您希望在表达式中使用数字 6 (0x36) 的 ASCII 值,则应使用单引号(即“6”),这将返回一个带符号的 integer 0x36,这是数字 6 的 ASCII 表示。

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.如果您希望在 C 中将字符串直接转换为 integer,您可以使用标准库 function,它会在您的应用程序中接收签名的指针“例如,返回一个签名的指针”, integer。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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