某日二师兄加入 XXX 科技公司的 C ++ 工程师开发岗位第 10 面:
面试官:理解
sizeof
操作符吗?二师兄:稍微理解(不就是求大小的嘛。。)
面试官:请讲以下如何应用
sizeof
?二师兄:
sizeof
次要是求变量或者类型的大小。间接应用sizeof(type)
或sizeof(var)
即可。面试官:嗯。
sizeof(int*)
、sizeof(int**)
和sizeof(int[4])
各返回什么?二师兄:前两者的返回值相等。在 32 位操作系统中返回 4,64 位操作系统中返回 8。
sizeof(int[4])
返回 16,是因为sizeof
运算时数组不会进化为指针。面试官:如果一个
int* p = nullptr
,那么对其进行sizeof(*p)
会产生什么?二师兄:返回 4。起因是
sizeof
在编译时求值,sizeof
只须要获取*p
的类型,并不对*p
求值。所以不会产生段谬误。面试官:上面三个
szieof
运算符,各返回什么?
#include <iostream>
#include <string>
int main(int argc, char const *argv[])
{
const char* str1 = "hello";
char str2[] = "hello";
std::string str3 = "hello";
std::cout << sizeof(str1) << std::endl;
std::cout << sizeof(str2) << std::endl;
std::cout << sizeof(str3) << std::endl;
}
二师兄:第一个返回 4 或 8,因为它是个指针,第二个是个数组,不过开端有个
\0
结束符,所以它的值是 6, 第三个不分明,然而等于sizeof(std::string)
。面试官:好的。应用
sizeof
对以下两个构造体求大小,
#include <iostream>
struct Foo
{
char c;
int i;
double d;
};
struct Goo
{
char c;
double d;
int i;
};
int main(int argc, char const *argv[])
{std::cout << sizeof(Foo) << std::endl;
std::cout << sizeof(Goo) << std::endl;
}
二师兄:
sizeof(Foo)
应该等于 16,而sizeof(Goo)
应该等于 24。因为须要内存对齐。面试官:好的。那你知内存对齐的准则是什么,为什么要内存对齐?
二师兄:额。。。应该须要以 8 位对齐吧。。。不是很分明为什么要内存对齐。
面试官:你晓得
sizeof(空构造体)
的后果是多少吗?二师兄:应该是 0 吧。
面试官:对只有一个函数的类进行
sizeof
运算后果是多少?二师兄:应该也是 0?
面试官:好的,回去等告诉吧。
让咱们复盘以下今日二师兄的体现。
内存对齐的准则是什么,为什么要内存对齐?
次要有以下准则:
- 构造体变量的首地址是其最宽根本成员类型大小的整数倍。
- 构造体每个成员绝对于构造体首地址的偏移量都是成员大小的整数倍。
- 构造体的总大小为构造体最宽根本成员类型大小的整数倍。
因为性能。为了缓存敌对(Cache friendly)。这是一个很大的话题,咱们明天聊不了太多。
sizeof(空构造体)
的后果是多少?
这里在 C 中是 0,在 C ++ 中是 1。C++ 标准规定,不同的对象不能领有雷同的内存地址。如果空类大小为 0,类的对象数组中的每个对象都领有了雷同的地址,这显然是违反规范的。
对只有一个函数的类进行
sizeof
运算后果是多少?
这里也是一个坑。要看这个函数是不是虚函数。如果不是虚函数,则后果是 1, 如果是虚函数,则大小是 4 或者 8。
聪慧的小伙伴,提到 4 或者 8. 就应该晓得是怎么回事了吧?
好了,今日份面试到这里就完结了,小伙伴们,对于明天二师兄的面试,能打几分呢?如果是你,以上的问题都能答复的上来吗?
关注我,带你 21 天“精通”C++!(狗头)