(1)关于声明和定义的区别(变量可以被声明多次但是只可以被定义一次)
声明:不分配内存空间
定义:为变量分配地址和存储空间,还可以指定变量的初始值(定义也是声明,因为在定义的时候我们就声明了他的名字和类型)
int a;//这样既是声明也是定义
int a = 3;//定义
extern int a;//声明,通过extern关键字声明变量而不是去定义它
extern int a = 3;//定义
函数的声明和定义比较简单,带{}就是定义,不带就是声明
一般除了extern,变量都是定义
(2)关于bool,和float与0的比较
bool flag;
if(flag)
{}
else
{}
//假设若abs(a)<1e-3的时候就算做是0
float flag;
if((flag<=1e-3)&&(flag>=-1e-3))
{}
else
{}
(3)sizeof和strlen区别
sizeof是操作符,strlen是库函数(同理还要记得new和delete是操作符,malloc和free是函数)
sizeof的参数类型多样,strlen只能是以'\0'结尾的字符串
数组被传入sizeof的时候参数不退化,但是作为strlen会退化为指针
sizeof的结果是在编译的时候计算出来的,strlen则是在运算时才计算出来
.的优先级高于前置++,但是如果前置加加是我们自己写的那他就不再是操作符而是函数所以会先执行前置加加
(4)标准的宏MIN
#define MIN(a,b) ((a)<(b)?:(a):(b))
(5)关于a与&a区别
int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a+1);
int *ptr2 = (int*)(a+1);
printf("%d,%d,%d\n",*(a+1),*(ptr-1),*(ptr2-1));
2,5,1
(6)C,C++的内存分配
一个C,C++程序在编译的时候存在5大存储区:
堆区,栈区,全局区,文字常量区,程序代码区
全局变量和静态变量在静态存储区域分配
函数的局部变量在栈区
动态内存分配在堆上分配
(7)strcpy,sprintf,memcpy
char *strcpy(char* dest, const char *src);//目的是把src的内容复制到dest中
int sprintf( char *buffer, const char *format, [ argument] … );//转换成字符串再放入的数组之中
sprintf(s, "%s love %s.", who, whom);把字符串的值放到数组s中
void *memcpy(void *dest, const void *src, size_t n)//拷贝的是字节,也就是内存块之间的拷贝
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
效率方面:memcpy最高,strcpy其次,sprintf最低
(8)关于拷贝构造函数与赋值运算符的认识
1.拷贝函数会生成新的类对象,而赋值运算符不会
2.拷贝构造函数是创建一个新类,所以不必担心两个对象是否相同,但是赋值运算符需要这个操作,而且赋值运算符如果原先对象中有内存分配我们还要释放掉他。
(9)C++中的继承
继承于A的函数在构造的时候一定会先调用父类的构造函数然后才是自己的,如果你把A的构造函数设置成私有的那么A就不能够被继承了。
(10)虚函数
class A
{
virtual void g()
{
cout<<"A::g"<<endl;
}
private:
virtual void f()
{
cout<<"A::f"<<endl;
}
};
class B:public A
{
void g()
{
cout<<"B::g"<<endl;
}
virtual void h()
{
cout<<"b::h"<<endl;
}
};
typedef void(*Fun)(void);
void main()
{
B b;
Fun pFun;
for(int i = 0;i < 3;i++)
{
pFun = (Fun)*((int*)*(int*)(&b)+i);
pFun();
}
}
输出结果:
B::g
A::f
B::h
B继承了A以后B中有一个虚函数表,第一个函数是B::g,第二个函数就是A::f,至于第三个函数虽然是B的虚函数但是却不在表里面,这点我也有点疑惑,有会的大神希望可以在评论下面给我解惑