繁体   English   中英

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

[英]What happens when I assign a string to an int?

如果我用字符串实例化一个int,那个int的值实际上是什么? 例如,对于以下代码:

#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);
}

我得到的每个执行的值都不同,例如:

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

要么

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

这些价值观是什么? 为什么他们总是不同? 什么是'a'实际存储?

int a = "abcd";

这在C中是非法的。

好吧,有点。 对于这种事情,C标准实际上并没有使用“非法”一词。 准确地说,这是一个约束违规 ,这意味着任何符合标准的编译器必须发出诊断消息(这可能是一个非致命的警告)。

表达式"abcd"char[5]类型的数组表达式(4表示字母加1表示终止\\0' )。 在大多数情况下,包括这个(如果它是有效的),数组表达式被隐式转换为指向数组的第一个元素的指针。 在转换之后,值的类型为char* ,它是指向'a'的指针。

没有从char*int 隐式转换,这就是初始化无效的原因。 您可以添加强制转换,这是一种显式转换:

int a = (int)"abcd";

这将存储在a字符串的内存地址,从转换char*int 在许多系统中,这种转换虽然合法,却会产生垃圾; 例如,在我输入的系统上, char*是64位, int只是32位。

旧版C语言(早于1989年)的编译器对隐式转换更加宽松,通常允许将整数和指针相互分配。 更现代的编译器,即使他们要求他们诊断出这个错误,也可能(或可能不会)生成执行隐式转换的代码。 (严格地说,行为是未定义的,但隐式转换很常见。)

如果您的编译器拒绝

int a = "abcd";

它正在做它的工作。 如果它只是警告你,它仍然在C标准方面做它的工作,但它实际上并没有通过生成隐式转换对你有所帮助。

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

至于printf调用的输出:

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

%s需要一个指向字符串的char*参数。 &a的类型为int* ,并不指向字符串。 行为未定义。 很可能printf将从a开头打印垃圾字节,直到碰巧遇到空字节(或崩溃)。

不要那样做。

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

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

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

%d需要int类型的参数。 &a的类型为int* 未定义的行为。 可能会打印的内存地址a十进制整数。 不要那样做。 如果你真的想打印的地址a ,做正确的做法是:

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

也许回答这个问题的最有效方法是漫步问题代码:

#include <stdio.h>

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

上面的行声明了一个名为a的int,并使用字符串“abcd”的地址初始化a。 这一行将导致编译器变得有点脾气暴躁,因为它会抱怨类似: warning: initialization makes integer from pointer without a cast

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

上面一行的对象似乎是打印一个字符串。 不幸的是, &a是变量存储在内存中的内存地址,看起来它就像你的系统上的15508632120x93E6DF1 该值不是ASCII或UTF-8字符串; 因此它似乎打印出垃圾: "?????W?"?O?Kp\\? 或者其他一些无意义的字符串,具体取决于a的地址。 当然,这条线会让编译器变得更加脾气暴躁; format '%s' expects type 'char *', but argument 2 has type 'int *'

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

上面的行尝试将a的值打印为有符号整数。 它也将出现废话,因为价值a是字符串“ABCD”的地址。 因此, a (作为有符号整数)的值将是字符串“abcd”存储在存储器中的地址的有符号整数表示。

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

上面的行尝试将a的内存地址打印为有符号整数。 与其他人一样,这很可能再次显得无稽之谈。

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

为了您的观赏乐趣,我添加了上面的行,输出:“ a as a string[abcd] ”。 这证明变量a已成功初始化,尽管(再次)编译器认为我们疯了: warning: format '%s' expects type 'char *', but argument 2 has type 'int' }

暂无
暂无

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

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