周
(周)
1
小明有一个 C++ 问题,所有答对的人会被颁发 “代码巨佬2” 奖项(以此贴为证)。
见上贴
题目:为什么 struct
不能连套?我的意思是这样:
struct a
{
a b = *this; // Compile Error!
};
你可能会说,这不科学,不然你就可以这样了:
a c;
a d = c.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b. ...
哪里带这样连环套的?呃。。。
但是,C++ 就是如此神奇,这个逻辑是不对的。给你举个反例:
struct a
{
a* b = this;
};
int main()
{
a c;
a* d = c->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b;
}
以上程序轻松通过了编译,完全没有问题!(Compile Easily,但是是真的!)
所以问题到底在哪里呢?请答出最本质的原因。
有答案请在本帖下面回复,我会在 8 月 6 日之前 24h 之内回复 WA / AC。
2 个赞
指针可以是空,不会无限递归,而普通变量不一样,这个指针指向它本身,没有问题
还有你要是用普通变量这么写,如果可以运行它的内存会炸掉,而指针指向一块内存你写c->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b
本质上和写c->b
没有区别
2 个赞
周
(周)
6
很接近了,请你详细解释一下:
‘’’
指针可以是空(但我写的不是空 ),不会无限递归(会无限递归),而普通变量不一样,这个指针指向它本身,没有问题(确实没有问题,这个逻辑正确√ )
还有你要是用普通变量这么写,如果可以运行它的内存会炸掉(为什么?),而指针指向一块内存你写c->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b->b
本质上和写c->b
没有区别(正确的√ )
‘’’
主要在于为什么普通变量不行,为什么内存会炸掉。
2 个赞
指针是始终只占一块内存指向一块空间,而dalao文中提到的指针指向了自己,有点类似于构成了一个闭环,所以不会占太多内存,普通变量是新调用了一块内存空间,所以内存会无线使用(如果此操作合法)
1 个赞
周
(周)
8
AC! (上,应为无限使用)
P.S. 这位才是dalao,我只是小蒟蒻。
补充说明:
这个和占用内存有关。
指针的定义:一个数值型地址,这个地址通向一段内存。
结构体定义:一个结构,里面包含多个变量。
这道题最关键的地方在于编译器怎么计算这个结构体的内存大小:
a* ptr; a b;
sizeof(ptr) = 8 // 32位系统上是 4
sizeof(b) = ??? // 需要计算
而第一种情况,一个结构体包含他自己,那么假如我们定义了一个结构体,如下:
struct a
{
a b;
int k;
}
那么令 sizeof(a) = x
,我们会神奇的发现 x=x+sizeof(int) → x = x + 4
\therefore 0 = 4 ,我表示:“???”
因此,编译器就不能算出这个结构体应该占用多少内存。为了防止这种未定义行为,编译时禁止了这种奇葩行为。即使结构体里没有其他变量,也不行。
但是,如果结构体只有一个指针,那么 sizeof(a) = sizeof(ptr) = 8
,这不就能算出来内存大小了,所以是可以的。
于是解释完了。
P.S. 此贴之后可能就很难快速更新大挑战系列了,希望有其他人可以代替我,继续更新:)
1 个赞
张瑜
(张瑜)
14
这是什么神奇的问题,我平时都不用,有没有大佬解释一下。