c 语言变量默认值问题

2018-02-23 23:01:09 +08:00
 thomaswang

声明的 int 类型为什么默认值是 0,结构体 tom.age 默认值是一个随机值呢? tom.name (UU\000\000\300EUUUU)这个默认值是什么啊?

2595 次点击
所在节点    问与答
22 条回复
wevsty
2018-02-23 23:14:53 +08:00
未显式初始化的变量其值是多少是一种未定义的行为。
未定义行为的结果取决于编译器怎么去处理。
kokutou
2018-02-23 23:27:31 +08:00
为什么不初始化!!!
lion9527
2018-02-23 23:34:44 +08:00
局部 int 变量未初始化时默认为随机值。
全局 int 变量未初始化时默认为 0。
msg7086
2018-02-23 23:44:25 +08:00
随机到了 0 而已,一样是随机的。谁告诉你局部变量有默认值的?
pkookp8
2018-02-24 01:10:30 +08:00
局部变量的值,gcc 的话是在栈上的,不初始化时的值取决于这块内存正好是什么值
举个例子
func1()
{
int a=123456;
printf a
}
fun2()
{
int a;
printf a
}
main()
{
func1();
func2();//这样应该是会打出 123456 的
}
一般来说我们会默认它为随机值
忘了什么编译器好像会自动初始化成一个特定值(微软带的那个?)
aheadlead
2018-02-24 01:30:06 +08:00
@pkookp8 一语中的:“局部变量的值,gcc 的话是在栈上的,不初始化时的值取决于这块内存正好是什么值”

纠正楼上和楼主一个细节:
你们看到的那都不是随机值,应该叫做不确定的值比较合适。
am241
2018-02-24 02:10:44 +08:00
@pkookp8 烫烫烫烫 cc=int 3
thomaswang
2018-02-24 07:55:51 +08:00
@wevsty 编译的时候每个变量的逻辑地址已经定了,运行的时候,对应的物理地址不定,所以这个值不确定,而且每次的值都不一样?
thomaswang
2018-02-24 07:56:55 +08:00
@kokutou 因为我发现不初始化那个 int id,它居然每次都是 0,我想知道为什么
thomaswang
2018-02-24 07:58:13 +08:00
@msg7086 哈哈,为什么每次都是 0 呢,这个叫什么随机
thomaswang
2018-02-24 08:01:04 +08:00
@aheadlead 多谢纠正,你能解释一下,为什么每次执行结果中,id 都是 0 吗
wevsty
2018-02-24 08:41:55 +08:00
@thomaswang

局部变量的声明只确定了使用的内存空间的地址,具体这个地址上的值是什么是不确定的。
不确定的原因多半是编译器的行为决定的。
比如:MSVC 在编译 debug 版本时对局部未初始化的 int 变量就会统一的设定为 0xcccccccc
这里说的随机实际上是,这个值不能确定的意思,并不代表会每次改变。
最后,切莫太纠结这种未定义的行为,依赖于未定义行为的代码是不具备任何可移植性的,因为它很有可能只能工作在某个编译器的特定版本上。
harry890829
2018-02-24 08:43:27 +08:00
有的编译器会对未显示初始化的变量进行初始化,有的不会,我印象中 gcc 这种情况下 id 一直会是 0,但是 vc++的话,就不会了。以前吃过亏,声明了一个指针,并没有初始化为 null,然后去判空处理,结果永远是非空,很蛋疼,记住要初始化
msg7086
2018-02-24 09:02:36 +08:00
@thomaswang
随机值不是说每次都会生成不同的值,而是内存里正好是什么,就是什么。要是正好是 0,那就一直是 0,但是也可能是别的什么东西。比如以下代码:

#include <stdio.h>
int main() {
int id01, id02, id03, id04, id05, id06, id07, id08, id09, id10, id11, id12, id13, id14, id15, id16, id17, id18, id19, id20, id21, id22, id23, id24, id25, id26, id27, id28, id29, id30;
printf("id01..10 = %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X\n", id01, id02, id03, id04, id05, id06, id07, id08, id09, id10);
printf("id11..20 = %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X\n", id11, id12, id13, id14, id15, id16, id17, id18, id19, id20);
printf("id21..30 = %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X\n", id21, id22, id23, id24, id25, id26, id27, id28, id29, id30);
return 0;
}

~# ./test
id01..10 = 00000000 00000000 00007FFC 23F86F40 0000560F 992EE580 0000560F 992EE790 00000000 00000000
id11..20 = 00000000 00000000 0000560F 992EE7DD 00000000 00000001 00007FCE FAA51FCA 00007FFC 23F86E3E
id21..30 = 00007FFC 23F86E3F 00000000 000000C2 00000000 00000000 00000000 00000000 00000000 00000000
~# ./test
id01..10 = 00000000 00000000 00007FFD A71865E0 00005635 4A21F580 00005635 4A21F790 00000000 00000000
id11..20 = 00000000 00000000 00005635 4A21F7DD 00000000 00000001 00007F38 76647FCA 00007FFD A71864DE
id21..30 = 00007FFD A71864DF 00000000 000000C2 00000000 00000000 00000000 00000000 00000000 00000000
~# ./test
id01..10 = 00000000 00000000 00007FFD 5A537250 0000564B D6EC8580 0000564B D6EC8790 00000000 00000000
id11..20 = 00000000 00000000 0000564B D6EC87DD 00000000 00000001 00007EFD 9C7E5FCA 00007FFD 5A53714E
id21..30 = 00007FFD 5A53714F 00000000 000000C2 00000000 00000000 00000000 00000000 00000000 00000000
~#
newtype0092
2018-02-24 10:17:20 +08:00
在看谭老的书?
linux40
2018-02-24 11:04:31 +08:00
@lion9527 是看的生命周期,static 和 thread_local 是 0,其它是未定义。
qq910438219
2018-02-24 11:16:18 +08:00
随手初始化 习惯
thomaswang
2018-02-24 13:29:19 +08:00
@newtype0092 谭永强? 不知道你说的是哪本,有说上面这个问题吗
newtype0092
2018-02-24 13:44:32 +08:00
@thomaswang 谭浩强啊,大学教材,重点讲解各种编译器未定义行为的问题~
thomaswang
2018-02-24 13:52:54 +08:00
@newtype0092 额,我没上过大学

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/432060

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX