C++关键字
1 startic(静态)变量的作用
a 函数体内部的静态变量在函数被调用过程中值保持不变(其值再下次调用时扔维持上次的值)
b 模块内部的静态全局变量可以被模块内部的函数访问,不能被模块外的其它函数访问
c 模块内的静态函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内
d 类内静态成员变量认为是类的成员,由类的所有对象共享访问;(在没有类的对象时,也可以使用它);(static成员变量初始化在类外)。而静态成员函数也是为了类服务,是类的内部实现,无法访问非静态数据成员(只能访问静态成员变量),只能调用其它的静态成员函数。
//static全局变量和普通的全局变量区别在于static全局变量只初始化一次。static局部变量只被初始化一次,下一次运算是依据上一次的结果值。
2 const作用
常类型的变量或对象的值是不能被更新(只读)的。
a 定义const常量
b 进行类型检查,消除隐患,例如 void f(const int i){}
c 避免魔数,也方便的进行参数的调整和修改 int Max = 期望值
d 保护被修饰的东西被意外的修改,增加程序的健壮性
e 为函数重载提供参考
f 节省空间(和define相比)和提高程序效率(不需要存储和读内存操作)
3 switch语句中case结尾是否必须添加break
一般要在case后添加break语句,没有遇到关键字break,那么匹配的case值后的所有情况都会被执行。
switch(c)语句中 c不可以是float类型。
4 volatile的作用
与关键字const对应,说明这个变量可能会被意想不到的改变。一般在多线程中修饰被多个任务共享的变量。
5 ASSERT()是什么
断言,ASSERT()是宏,用来捕获非法输入。如果括号内部条件不满足就会终止运行。assert()是个函数,可以在release版本下使用。一般来说assert()只检验一个条件,如果同时两个条件,无法判断具体那个出了问题。
6 枚举变量的值如何计算
默认为前一个变量值加1,如果没有即是默认为0。可重复可单独赋值,例如 enum{a,b=5, c,d=4,e} 输出 0 5 6 4 5
7 char str[] =”abc”, char str1[]=”abc”str与str1不相等
str与str1是字符数组,有各自的存储区,指向的是各自存储区的首地址。而char* str = “abc”;char* str1 = “abc”; 相等。 str是字符指针,不分配存储区,abc以常量方式存在与常量区,str和是str1指向地址的首地址,相同。(&str和&str1是指针自己的地址,不相同)
8 new/delete与malloc/free的区别
1 new是运算符,malloc是函数
2 new可以自动计算需要分配内存的空间大小
3 new是类型安全的,int* a=new float会报错
4 new将调用构造函数,delete析构函数
5 new不需要库文件支持
需注意的是delete后,需要将指针指向置为空。
9 实现string函数体 (经典问题)
class mystring
{
public:
mystring(const char* str=nullptr);
mystring(const mystring& other);
~mystring();
mystring& operator = (const mystring& other);
private:
char* data;
}
mystring::~mystring()
{
delete[] data;
data = nullptr;
}
mystring::mystring(const char* str)
{
if(str==nullptr)
{
data = new char[1];
data[0] = '\0';
}
else
{
data = new char[strlen(str)+1];
strcpy(data, str);
}
}
mystring::mystring(const mystring& other)
{
data = new char[strlen(other.data)+1]; //可以直接访问类的成员变量...
strcpy(data, other.data);
}
mystring& mystring::operator=(const mystring& other)//返回值是引用可以实现a=b=c的赋值\参数为常量引用可提高效率
{
if(this==&other)
return *this; //对象的引用
delete[] data; //释放原先的内存
data = nullptr;
data = new char[strlen(other.data)+1];
strcpy(data, other.data);
return *this;
}
10 c++中关键字explicit的作用
声明为explicit的构造函数不能在隐式转换中使用。
sizeof 和指针和预处理
1 strlen(“\0”)=? sizeof(“\0”)=?
strlen是函数,碰到第一个字符串结束符’\0’为止,停止计数(不包括\0),参数只能为char*,必须以’\0’结尾;sizeof是关键字,以字节形式给出操作数的存储大小,操作数可以是表达式或者类型名(sizeof(int))。大部分编译程序的sizeof都是在编译期计算的,strlen的大小是运行期确定的。可以这么说,sizeof只关心分配的空间大小,strlen只关心存储的数据内容。前者为0, 后者为2(常量字符串结尾有个\0占一个字节);
例:
char str[10] = “1234”; sizeof(str) = 10; strlen(str) = 4;
char* p = new char[10];sizeof(p) = 4;p是指针; strlen(p)=0因为没有初始化没有定义\0,所以为随机值;sizeof(*p)=1;
char* a =”123456”;strlen(a)=6;sizeof(a)=4;
2 对于结构体而言,为什么sizeof返回值一般大于期望值?
为了使CPU的性能达到最佳,编译器对struct结构进行了4的倍数(32位)8的倍数(64位)字节对齐;
例1:
struct test
{
char x1;
short x2;
float x3;
char x4;
}
编译器默认对struct进行边界对齐,x1占用和x2相同,2;x1+x2=4;正好是自然边界地址上;x3是结构所有成员中要求的最大边界单元;x4为4;一共12;
字节对齐准则:
a 结构体的总大小为最宽接本类型成员大小的整数倍
3 指针进行强制类型转换后与地址进行加法运算,结果是
例:
struct A
{
long x1;
char* x2;
short