简体   繁体   English

将字符串分配给int时会发生什么?

[英]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? 如果我用字符串实例化一个int,那个int的值实际上是什么? 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? 什么是'a'实际存储?

int a = "abcd";

This is illegal in C. 这在C中是非法的。

Well, sort of. 好吧,有点。 The C standard doesn't actually use the term "illegal" for this kind of thing. 对于这种事情,C标准实际上并没有使用“非法”一词。 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' ). 表达式"abcd"char[5]类型的数组表达式(4表示字母加1表示终止\\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' . 在转换之后,值的类型为char* ,它是指向'a'的指针。

There is no implicit conversion from char* to int , which is why this initialization is invalid. 没有从char*int 隐式转换,这就是初始化无效的原因。 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 . 这将存储在a字符串的内存地址,从转换char*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. 例如,在我输入的系统上, char*是64位, int只是32位。

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. 旧版C语言(早于1989年)的编译器对隐式转换更加宽松,通常允许将整数和指针相互分配。 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. 如果它只是警告你,它仍然在C标准方面做它的工作,但它实际上并没有通过生成隐式转换对你有所帮助。

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. 底线:分配给a的值是垃圾,如果你的编译器没有抱怨它,找出你需要做什么选项来让它这样做。

As for the output of your printf calls: 至于printf调用的输出:

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

%s requires a char* argument that points to a string. %s需要一个指向字符串的char*参数。 &a is of type int* , and does not point to a string. &a的类型为int* ,并不指向字符串。 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). 很可能printf将从a开头打印垃圾字节,直到碰巧遇到空字节(或崩溃)。

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 . 如果你的程序还没有在这一点上坠毁,这种打印的值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. 该值是垃圾,通常可能是字符串文字地址的转换值,或者只是该地址的低32位。

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

%d requires an argument of type int . %d需要int类型的参数。 &a is of type int* . &a的类型为int* Undefined behavior. 未定义的行为。 This might print the memory address of a as a decimal integer. 可能会打印的内存地址a十进制整数。 Don't do that. 不要那样做。 If you really want to print the address of a , the correct way to do it is: 如果你真的想打印的地址a ,做正确的做法是:

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". 上面的行声明了一个名为a的int,并使用字符串“abcd”的地址初始化a。 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 . 这一行将导致编译器变得有点脾气暴躁,因为它会抱怨类似: 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. 不幸的是, &a是变量存储在内存中的内存地址,看起来它就像你的系统上的15508632120x93E6DF1 This value is not an ASCII or UTF-8 string; 该值不是ASCII或UTF-8字符串; hence it appears to print out garbage: "?????W? , "?O?Kp\\? 因此它似乎打印出垃圾: "?????W?"?O?Kp\\? , or some other nonsense string, depending on what the address of a happens to be. 或者其他一些无意义的字符串,具体取决于a的地址。 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. 上面的行尝试将a的值打印为有符号整数。 It will also appear as nonsense, Since the value of a is the address of the string "abcd". 它也将出现废话,因为价值a是字符串“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. 因此, a (作为有符号整数)的值将是字符串“abcd”存储在存储器中的地址的有符号整数表示。

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

The above line attempts to print the memory address of a as a signed integer. 上面的行尝试将a的内存地址打印为有符号整数。 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] ". 为了您的观赏乐趣,我添加了上面的行,输出:“ 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' } 这证明变量a已成功初始化,尽管(再次)编译器认为我们疯了: warning: format '%s' expects type 'char *', but argument 2 has type 'int' }

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

相关问题 当我在C中将long int分配给int时会发生什么? - What happens when I assign long int to int in C? 当我将一个字符串分配给一个字符时会发生什么? - What happens when I assign a string to a char? 当我们将一个 int 分配给一个由 2 个 int 组成的数组时会发生什么? - What happens when we assign one int to an array of 2 ints? 当我在 printf() 中的字符串后添加一个带加号的 int 时会发生什么 - What happens when I adding an int with a plus sign after the string within printf() 如果我们将负整数分配给无符号整数会发生什么? - What happens if we assign a negative int into an unsigned int 当我们将返回类型为void的函数调用返回值分配给int变量时会发生什么? - What happens when we assign a function call return value with return type void to a int variable? 如果我为 int 指针分配一个浮点变量地址会发生什么,反之亦然? - What happens if I assign to an int pointer a float variable address and vice-versa? 将int转换为float时在后台会发生什么 - what happens at background when convert int to float 评估 `int x = -2147483648` 时会发生什么? - What happens when evaluating `int x = -2147483648`? 字符串仅包含“ \\ 0”时会发生什么? C - What happens when a string contains only '\0'? C
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM