C++面试笔记--const、sizeof
- 首先来一个关于const的全面的解释,先看一波代码,之后再进行详细的分情况解释
int b=;
const int *a=&b;//指向一个int常量的指针
int const *a=&b;//和上面类似
int * const a=&b;//一个常量的指针a指向一个地址
const int * const a=&b;//一个常量指针指向一个常量情况①:第一个和第二个的情况是一样的。他们都是定义了一个指针a指向一个变量b的地址,之后a的指向是可以改变的,但是他指向的东西是一个常量
情况②:第三个表示的是a是一个常量的指针,*a不能够改变,就是它的指向是不能改变的,永远只能指向b的地址。但是它指向的那个东西不是一个常量,*const a在进行定义的时候就必须为它进行初始化,因为之后它是不能改变的了。
情况③:第四个表示的是a是一个常量指针,指向的东西也必须是一个常量。意思差不多就是情况1和情况2的结合。 - 之后我们再来看一下const的成员函数。
我们一般是在不需要改变对象的成员函数上面加上const,格式:int gety() const;表明这个函数里面的变量的值是不能进行修改的。
注:任何不需要修改成员数据的函数都是应该声明为const函数的。 - 面试题一:const与#define相比有什么不同?
C++语言可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的优点:
(1)const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行 类型安全检查,而对后者只是进行字符替换,没有类型安全检查,并且在字符替换中可能产生意料不到的错误(边际效应)。
(2)有些集成话的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
- 面试题二:const有什么用途?请至少说明两种?
(1)可以定义const常量。(2)const可以修饰函数的参数和返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 - 面试题三:在const成员函数中,如果想要修改函数中变量,该怎么办?
我们可以在类的成员变量前面加上mutable修饰词修饰,这样就能在const函数中修改成员变量了。 - 这里介绍sizeof的一些面试题
- 面试题一:
#include<iostream>
using namespace std;
struct
{
short a1;
short a2;
short a3;
}A;
struct
{
long a1;
short a2;
}B;
int main ()
{
char* ss1 = "";
char ss2[] = "";
char ss3[] = "";
int ss4[];
char q1[] = "abc";
char q2[] = "a\n";
char* q3 = "a\n";
char *str1 = (char *)malloc();
void *str2 = (void *)malloc();
cout<<"sizeof(ss1):"<<sizeof(ss1)<<endl;
cout<<"sizeof(ss2):"<<sizeof(ss2)<<endl;
cout<<"sizeof(ss3):"<<sizeof(ss3)<<endl;
cout<<"sizeof(ss4):"<<sizeof(ss4)<<endl;
cout<<"sizeof(q1):"<<sizeof(q1)<<endl;
cout<<"sizeof(q2):"<<sizeof(q2)<<endl;
cout<<"sizeof(q3):"<<sizeof(q3)<<endl;
cout<<"sizeof(A):"<<sizeof(A)<<endl;
cout<<"sizeof(B):"<<sizeof(B)<<endl;
cout<<"sizeof(str1):"<<sizeof(str1)<<endl;
cout<<"sizeof(str2):"<<sizeof(str2)<<endl;
return ;
}解析:ss1是一个字符指针,指针的大小是一个定值,就是4字节,所以sizeof(ss1)是4字节
ss2是一个字符数组,这个数组最初未定大小,由具体填充值来定。填充值是“0123456789 ”。1个字符所占空间是1字节,10个就是10字节,再加上隐含的“\0”,所以一共是11字节。
ss3也是一个字符数组,这个数组开始预分配100,char类型占用空间(1),所以它的大小一共是100字节。
ss4也是一个整型数组,这个数组开始预分配100,但是每个整型变量(int)所占用空间是4,所以它的大小一共是400字节。
q1与ss2类似,所以是4字节。
q2里面有一个“\n”,“\n”算做一位,所以它的空间大小是3字节。
q3是一个字符指针,指针的大小是一个定值,就是4,所以sizeof(q3)是4字节。
A和B是两个结构体,在默认情况下,为了方便对结构体内元素的访问和管理,当结构体内的元素的长度都小于处理器的位数的时候,便以结构体里面最长的数据元素为对齐单位,也就是说,结构体的长度一定是最长的数据元素的整数倍。如果结构体内存在长度大于处理器位数的元素,那么就以处理器的位数为对齐单位,但是结构体内类型相同的连续元素将在连续的空间内,和数组一样。
结构体A中有3个short类型变量,各自以2个字节对齐,所以sizeof(A)是为6字节。结构体B中a1以4字节对齐,a2以2字节对齐,则结构体大小为6字节,但是结构体的长度一定是最长数据元素的整数倍,显然6不是4的整数倍数,补空字节,增到8字节,符合所以条件。故sizeof(B)为8字节。
str1和str2都是字符指针,都是4字节。
结果::
这里补充一下在不同位数的系统中,各种数据类型所占用的字节数:(一般都是32位的)
16位编译器
char :1个字节
char*(即指针变量): 2个字节
short int : 2个字节
int: 2个字节
unsigned int : 2个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节32位编译器
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节除了*与long随操作系统子长变化而变化外,其他的都固定不变(32位和64相比)
- 面试题二:以下代码为32位机器编译,数据是以4字节为单位,这两个类型的输出结果为什么不同?
class B
{
private:
bool m_bTemp1;
int m_nTemp;
bool m_bTemp2;
};
class C
{
private:
int m_nTemp;
bool m_bTemp1;
bool m_bTemp2;
};
cout << sizeof(B) << endl;
cout << sizeof(C) << endl;解析:编译器会对结构体进行对齐处理,根据对齐原则。
类型B情况如下:
| bool |-----|----|----|
|-----------int---------|
| bool |-----|----|----|
类型C情况如下:
|-----------int-----------|
| bool | bool |----|----|
事实表明,对齐原则十分靠谱,就这样计算的话准没错的。 - 面试题3:以下代码的输出结果是多少?
char var[]
int test (char var[])
{
return sizeof(var);
}数组作为参数传递,传递的是一个首地址,等价于*var,已退化成一个指针了,所以大小是4。
答案:4.
- 一个空类占多少空间?多重继承的空类呢?
#include<iostream>
using namespace std;
class A1
{
};
class A2
{
};
class B : public A1
{
};
class C : public virtual B
{
};
class D : public A1,public A2
{
};
int main ()
{
cout <<"sizeof(A1):" << sizeof(A1) << endl;
cout <<"sizeof(B):" << sizeof(B) << endl;
cout <<"sizeof(C):" << sizeof(C) << endl;
cout <<"sizeof(D):" << sizeof(D) << endl;
return ;
}以上答案分别是1,1,4,1。这说明空类所占空间为 1,单一继承的空类空间也是 1,多重继承的空类空间还是 1,但是虚继承涉及虚表(虚指针),所以大小为 4。
答案:
一个空类占空间为 1 ,多重继承的空类所占空间还是 1,但虚继承的为 4。
内联函数和宏的差别
①:内联函数和普通的函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接被镶嵌到目标代码中,而宏只是一个简单的替换。
②:内联函数需要做参数类型检查,这个是它的优势。
③:inline通过增加空间消耗换来的是效率的提高,这方面和宏是一样的。但是inline更加安全。- 内联函数一般用于以下情况:
①:一个函数不断被重复的调用
②:函数只有简单的几行,且函数内包含for,while,switch语句。当我们进行一个工程项目的时候,如果有一小段代码频繁的出现,我们可以定义为内联函数。
- 内联函数一般用于以下情况:
C++面试笔记--const、sizeof的更多相关文章
- php面试笔记(2)-php基础知识-常量和数据类型
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 面试是每一个PHP初学者到PHP程序员必不可少的一步,冷 ...
- Java高级开发工程师面试笔记
最近在复习面试相关的知识点,然后做笔记,后期(大概在2018.02.01)会分享给大家,尽自己最大的努力做到最好,还希望到时候大家能给予建议和补充 ----------------2018.03.05 ...
- php面试笔记(5)-php基础知识-自定义函数及内部函数考点
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而函数相关的考点 ...
- php面试笔记(3)-php基础知识-运算符
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而运算符相关的考 ...
- GitHub标星125k!阿里技术官用3个月总结出的24万字Java面试笔记
最近收到一位粉丝的回馈! 这位粉丝已经成功入职阿里了小编很是羡慕啊! 今天就把这份30w字Java面试笔记给大家分享出来,说来也巧这份资料也是由一位阿里技术官整理出来的这算不算是"搬起石头砸 ...
- <转载> C++笔试、面试笔记
这些东西有点烦,有点无聊.如果要去C++面试就看看吧.几年前网上搜索的.刚才看到,就整理一下,里面有些被我改了,感觉之前说的不对或不完善. 1.求下面函数的返回值( 微软) int func(x) ...
- C++面试笔记--指针和引用
面试一:指针与引用的区别? 答案: (1)非空区别.在任何情况下都不能使用指向空值的引用.因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针 ...
- 20140319 const sizeof define 编译时分配内存
1.面试宝典预处理,const,sizeof Define作用定义函数: //用一个宏定义FIND求一个结构体struc里某个变量相对于struc的偏移量,如FIND(student,a)//等于0 ...
- C#面试-关于const和readonly(看了一个点赞很多的帖子有感而发!)
前景提要: 最近大家都在面试,讨论最多.最基础的问题,莫过于“关于const和readonly常见的笔试题剖析”,等等的大牛解析.我就是一个小菜,只不过,有点不敢苟同大牛的意见.废话少说,进入重点. ...
随机推荐
- html 常用代码块
解决外边框不计入div尺寸的代码-moz-box-sizing: border-box;box-sizing: border-box;-webkit-box-sizing: border-box; 手 ...
- dbca 快速健建库
[oracle@e0946877f272 ~]$ dbca -silent -createDatabase -templateName $ORACLE_HOME/assistants/dbca/tem ...
- AMD 规范
AMD(异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件. AMD 定义了一套 JavaScript 模块依赖异步加载标准 ...
- 非maven项目下载maven的jar
很多时候我们需要jar,可惜项目不是maven的,但是我们只有一个maven的坐标,那怎么办? 比如: <dependencies> <dependency> <grou ...
- ajax中error函数参数详解
xhr.status和error函数中的status是不一样的,error函数中的status主要包括:"success"."notmodified".&quo ...
- Mstar 编译器的搭建
机顶盒: 1.解压“mipsisa32-elf-3.4.4-20101123.i386linux.tar.gz" 应用编译器 2.mips-4.3-51-mips-linux-gnu-i68 ...
- 用Json Template在Azure上创建Cisco CSR路由器
Azure的ARM模式可以通过Json的模板创建VM.本文以Cisco的CSR的image为例,介绍如何用Json的创建VM. 一.Cisco CSR的Image 首先把Cisco CSR的image ...
- [Chapter 3 Process]Practice 3.2 Including the initial parent process, how many processes are created by the program shown in Figure?
3.2 Including the initial parent process, how many processes are created by the program shown in Fig ...
- webapi中使用token验证(JWT验证)
本文介绍如何在webapi中使用JWT验证 准备 安装JWT安装包 System.IdentityModel.Tokens.Jwt 你的前端api登录请求的方法,参考 axios.get(" ...
- c# linq查询语句详细使用介绍
本文介绍Linq的使用方法 linq介绍 LINQ只不过是实现IEnumerable和IQueryable接口的类的扩展方法的集合. LINQ可以查询IEnumerable集合或者IQueryable ...