我叫小狼,是一个有规划、懂遵守的美男子一枚。
基础问题
1、static变量有什么作用
一般局部变量声明,是在栈空间开辟内存。但是static关键字声明的变量是在静态全局区开辟空间的。不同之处就是:一般局部变量出了他的作用域,就会销毁,其值就没了;但是静态变量则不然,出了作用域,他的值是保留的。
static全局变量和普通全局变量的区别:static全局变量只初始化一次,这样做的原因是为了防止在其他文件单元中被引用;
static局部变量和普通局部变量的区别:static局部变量也只初始化一次,下一次运算的依据是上一次运算的结果值;
static函数与普通的函数的区别:作用域不同。静态函数只能在本cpp中引用,在其他cpp中不可引用。
静态数据成员的特点:
一:对于非静态数据成员,每个类对象有各自自己的复制品;静态成员则是该类所有对象共同访问。
二:存储在静态全局区,定义时要分配空间。所以不能在类声明中定义。静态成员的初始化要在类外。
三:可以实现数据隐藏。静态全局变量可以是私有的,而普通全局变量则不可以是私有的。
(问为什么只初始化一次{因为没被销毁啊,栈中的auto,自动销毁})
(问头文件中定义变量行不{不得的哦,因为会造成程序错误,资源浪费的问题,所以,不推荐在头文件中定义任何变量,去构造函数中吧})
2、const有哪些作用
const是常类型。被他修饰的其值是不变的。他可以修饰变量,也可以修饰指针,也可以修饰函数参数,可以修饰函数返回值。
作用:定义常量,具有不可变性;保护被修饰的东西,防止被篡改;避免不必要的内存分配,提高程序效率(不为普通的const常量分配存储空间,而是将他们保存到符号表中)。
问什么时候使用const关键字?
修饰一般常量
修饰常数组
修饰常对象
修饰常指针
修饰常引用(常引用哦,主要是用来防止传入函数的实参,在不知情的情况下被篡改)
修饰函数常参数
修饰函数返回值
修饰类的成员函数
3、switch case语句必须添加break吗?为什么
不是啊,如果出现的集中case情况都会导致一种结果,执行同一条指令,那么就在左后一个case之后执行完指令后break就行了。
执行知道遇到break;注意,switch中的数可以是int long char 枚举,,唯独不能是float的哦
4、volatile(解优化)在程序设计中有什么作用
没见过啊。。。。
volatile一般用于修饰多线程间被多个任务共享的变量和并行设备硬件寄存器。(系统每次用到它时,都会直接从内存中取值,而不是从寄存器中取值(因为寄存器中的值可能是被其他线程修改过的了)吗,这样讲,这个关键字修饰的变量,则不会编译器优化。)
(总结):每次读取这个变量,都要小心的从内存中读取而不是寄存器中的备份。
5、断言ASSERT()是什么
判断有没有异常发生,相当于C++中的try语句吧。
定义在<assert.h>头文件中。一般用于判断程序中是否出现了非法数据。在程序运行时,它计算括号内的表达式的值,若为false(0),程序报错并终止运行,同时查找错误。不为0则继续执行后面语句。
注意:ASSERT只在debug中有;release中则忽略。assert()是函数,ASSERT是宏,函数的话就可以在release版本中使用了。
6、枚举变量的值怎么计算
比如枚举四个变量:春夏秋冬,那么春值就是0,夏值就是1,以此类推。
第一个元素不赋值,默认为0;接下来某个枚举值的默认值为前一个变量+1;如enum{a,b=5,c,d=4,e} ==>则a=0,b=5,c=6,d=4,e=5.
7、char str1[]="abc";char str2[]="abc";str1和str2不相等,怎么回事?
我去,这是一个字符串常量,在常量区存储。str和str2是两个指针,指向同一位置,为啥不一样啊》》》》》
str1和str2都是字符数组,在栈上开辟的内存,首地址不一样,所以,str1不等于str2.
但是如果是 char *str3=“abc”;char *str4=“abc”则p1=p2;因为是字符指针,开辟在全局区,指向同一位置。
8、为什么main(int argc,char * argv[])有的会带参数?argc和argv是什么含义?
不记得了。。
第一个参数是int类型的,表示命令行参数的数目;第二个是一个指向字符串的指针数组,指向的是这组参数的第一个元素。
9、C++里面的所有动作都是由main函数引起的?
当然不是。预编译过程就是在main函数之前完成的,比如宏定义展开,头文件包含等。。。
10、*p++和(*p)++等价吗?为什么
一般来讲不等价。* 和++ 优先级不同,++的优先级要高一些。*p++是先结合++,但++为后加加,所以意味着指针++一个类型的长度,如果是int型,指针跳4个字节。
而()的优先级大于++,所以先解引用,得到指针指向的值,然后在这个值上++;
注意优先级问题:括号数组下标中括号、单目运算符和sizeof、算数运算符、位移运算符、关系运算符、逻辑运算符、三目运算符。
11、前置运算和后置运算有什么区别
前置运算是在执行这条语句前对与前置运算符结合的变量进行前置运算;后置运算是在执行这条语句后再对与后置远算符结合的变量进行后置运算。
内存中值和寄存器中值有差别:++a(内存中为a,寄存器中是a+1);a++(寄存器中是a,内存中是a+1)
12、a是变量,执行(a++)+=a语句是否合法
其实这个是看左值或者右值吧。表达式是不能作为左值的。所以不合法。
左值:可以出现在表达式左边的值;它是可以被改变、是存储数据值得那块内存的地址。也可以称作变量的地址。
右值:不可以出现在表达式左边的值,是指存储在某内存地址中的数据。
所以上述语句是不合法的。
a++指把a值放进寄存器中后,对原内存中的值进行+1操作。左后结果得到的是内存中的数据,也就是右值
++a是指把a的值拿出来,对其+1后的数据放进寄存器中,得到的是地址,也就是左值。
13、如何进行float、bool、int、指针变量与“零值”的比较
float单精度,不能用“==”;只能用逼近从左边或者右边接近一个小数,则可认为相等,比如<0.00001,则认为和0值相等。
bool有两个值,一个true(非0值)一个false(0)==0或者==false;
int 可以直接==0;
指针 ==NULL
int型是对的
指针是对的
float是对的
bool应该
if(flag)
if(!flag)
14、new、malloc(delete、free)区别是什么
C++:new int / new int[] 和delete delete[] p
C:malloc(字节大小sizeof(类型))memset来初始化这段内存空间,最后free()
一:new自动计算分配的内存空间,malloc是需要手动计算分配的内存空间
二:new int[]带具体类型的指针,而malloc则返回void类型的指针
三:new是类型安全的,int* p=new float[];这是会报错的。而int* p=malloc(2*sizeof(float))则不会
四:new调用构造函数,delete则调用析构函数;malloc和free不会
五:malloc和free需要stdlib.h头文件支持。而new和delete不需要
15、什么时候需要将引用作为返回值
需要返回这段内存的首地址的时候,可以返回引用。
一般返回一个对象的时候用引用作为返回值。引用作为返回值,可在内存中不产生返回值的副本,不涉及对象的复制拷贝,提高程序的安全性和效率。
16、变量名618Software是否合法
不合法,数字作为变量首字母了;首字母可以是下划线或者字母,其余的可以是下划线,字母,数字。
17、C语言中整形变量X小于0的,是否可知X*2也是小于0的呢?
不一定,当X*2超出整形的范围时,可能是大于0的。
18、exit(status)是否和从main()函数返回的status等价
不知道。
C语言标准情况下是等价的,但在返回时使用main函数的局部数据,则return就不行了。
return为返回函数调用,当时main函数时,则为退出程序。
exit是强行退出程序,括号内提交给系统的数据方便程序员记录是因为什么原因退出的。
19、已知String类定义,如何实现其函数体
分几部分对其成员函数进行实现。
无参构造函数、有参构造函数、拷贝构造函数(不能是虚函数)
一般的成员函数
析构函数(可以是虚函数,也可以不是)
普通构造函数
复制构造函数
赋值函数(赋值操作)
析构函数
成员变量
#include<iostream>
class String
{
public:
String(const char *str=NULL); //普通构造函数
String(const String &str); //复制构造函数
~String(); //析构函数
String& operator=(const String &rth); //赋值操作
private:
char* m_data; //用于保存字符串
};
//构造函数的目的就是初始化类的成员函数。
//接下来实现
String::String(const char *str=NULL)
{
if(str==NULL)
{
m_data=new char[1];
m_data=" ";
}
else
{
m_data=new char[strlen(str)+1];
strcpy(m_data,str);
}
}
String::String(const String &str) //str是String的实例对象,需要将他的成员函数一个一个的拷贝到另一个对象(this)中
{
m_data=new char[strlen(str.m_data)+1];
strcpy(this->m_data,str.m_data);
}
String::~String()
{
delete[] m_data;
}
String& String::operator=(const String &rth) //构造函数和析构函数都没有返回值,,若有函数返回值,则:返回值 类别::函数名称(参数)
{
if(this == &rth)
return *this;
delete[] m_data;
m_data=new char[strlen(rth.m_data)+1];
strcpy(m_data,rth.m_data);
return *this;
}
20、C++中如何实现模板函数的外部调用
不会。
export关键字能实现。类似于extern(可以范文在其他文件中的变量和对象)
对于模板函数,可以在头文件中声明模板类和模板函数,在代码文件中使用关键字export来定义具体的模板类和模板函数。然后在其他童虎
21、C++中关键字,explicit有什么作用
显示调用。
普通构造函数能被隐式的调用;但被explicit修饰的构造函数只能被显式的调用。
String str=“hello”//隐式调用构造函数
String str1=String(“hello”)//显式的调用构造函数
22、C++中异常处理方法以及使用了哪些关键字
一、中断。二、返回值。try catch throw
关键字对着呢(把可能发生异常的部分放到try中,catch语句负责具体的异常类型)
23、如何定义一个类的成员函数为回调函数。
不知道。。。
如果把函数指针作为参数传递给另一个函数,当这个指针被用为调用它所指的函数时,此时就可以称它为回调函数。
定义一个类的成员函数为回调函数需要以下3个步骤:
一、声明(回调函数必须声明成静态的)
二、定义
三、设置触发条件
BOSS:小狼,你回答成这样,你觉得自己录用的可能性大不
小狼:BOSS,我觉得,录用我会给我提供成长的机会,这样才能更好的回馈公司不是,不然我失去的可能只是一次较好提升自己的机会而已,而您失去的是一个能为公司盈利做贡献的人啊,多不划算,要了我吧,要了我吧 ^_^
BOSS:-_-!!