using namespace是使用命名空间区分不同类相同名字的函数名或者名称空间:: 的形式
char 1字节 short 2字节 int 4字节 float 4字节 long 4字节 double 8字节 long long 8字节(不管是多少位系统) 1字节=8位
short值设为0减1变成了65535,可以看到发生了溢出
int a=ture; //a为1
int b=false ;//b为0
bool a=-100 ; //a为true
3.45E+6=3.45*1000000 8.33E-4=0.000833
运算符重载:使用相同符号进行多种操作,比如除法/,可以对int进行除法,也可以对long除法
static_cast<>可用于将值从一种类型转到另一种类型比如:static_cast<long > (thorn)
“s”表示字符s和\0
strlen()计算可见的字符,数组的长度不短于strlen(数组)+1所以数组初始化的时候都是new char [strlen(数组)+1]
strcat()将字符串附加到另一个的末尾
inflatable如果是结构体那么 inflatable gifts[100]表示100个inflatable的结构体数组
inflatable guest[2]= //等号表示对inflatable结构体初始化
{
{“bambi”,0.5,21.99}, //这个结构体数组,对第一结构体初始化
{“god”, 100 , 355.88} //对第二结构体初始化
}
共用体union能存储不同数据,但同时只能存储其中一种类型,结构可以同时存储int ,long和double,共用体则是只能存储int,long或double,共用体长度为最大成员长度
enum bigst{ first,second=100,third }; // 这里third为101,不是2
double cup=4.5 如果把&cup理解成引用,那么&cup是cup值的地址, *(&cup)才是cup
面向对象和面向过程的区别在于oop强调在运行阶段而不是编译阶段进行决策,c++采用的方法是new来达到动态分配内存
long *fellow; //这样初始化是不对的,第一句没有初始化指针给他赋值,也即野指针
int *pt;
pt={int *} 0x32434235; // 注意等号左右类型匹配
c初始化指针:
int pt;
int *pn=&pt;
C++指针初始化:
int *pt=new int; //new int 告诉程序需要存储int内存,new根据多少字节找到这样内存并且返回地址
sizeof(*pt) //只要是指针的大小不管是char还是int还是double都是4(字节)
double wage[3]={1000.0,2000.0,3000.0}; sizeof(wage)=3(也即3个元素)*8(double8字节)=24
变量在函数当中保存在栈中,而new出来的放在堆中
静态联编:int a[10] // 编译时分配数组长度
动态联编:在运行时分配长度
动态联编的做法:
int size;
cin>>size;
int*pz=new int(size);
delete[] pz;
short tell[10];
一定要在这样的思路去理解(按照步长去理解);
&tell[0]是tell[0]地址,步长为short字节,所以&tell[0]+1将地址值+2,同理tell+2中tell是tell[0]地址,步长为double类型的字节,而&tell中tell是tell[0]的地址,再对他取址,步长为double字节*10,所以&tell+1将地址+20
cout输出数组animal的地址这样:cout<<(int *) animal<<endl;
如果ps是对象的指针,调用方法要么(*ps).name要么ps->name
节省内存的方法:假设程序读取100字符串,每个字符串长度不同,可以创建一个数组,包含100个char指针,new出根据每个字符串需要的长度动态分配内存,new长度为str[a]+1
局部变量:放在函数里 。 成员变量:放在类中
new却没有delete导致内存泄露,后果:程序内存耗尽而崩溃
c++数据存储的3中方式:
自动存储:数据生命和函数绑定,函数结束收回
静态存储:static
动态存储:new delete
class A a;那么a存在栈上
class A a=new A();放在堆中,末尾的()说明对象创建后,自动调用A的构造函数,如果没有,自动补上默认的构造函数,a是A的引用,指向A的内存地址,
对于Dog dog;栈中占用的大小是Dog类成员变量大小之和
Dog *p=new Dog();在栈中开辟4字节控件存放地址,指向堆中对象
偷懒机制:对于|| (或)如果左边为true,不管右边,直接true,同理&&
arr[i]==*(arr+i)
&arr[i]==arr+i //地址加上i是加了i个单位字节的地址
*(ar2+r) 为ar2[r]
*(ar2+r) +c 由于*(ar2+r) 为ar2[r]是一个值,一个值加一个值还是一个值
const int *p 说明指针指向的内容不能改变,但是指向的地址可以改变
int *const p 指针指向的地址不能边,内容可以改
注意const int *p和int const *p是一回事,不同的是const在*左边还是右边
如果一个函数传参是一个结构体或者对象,不要把对象传进去,传引用或者指针,保证函数不改变对象的内部结构,用const限定,传引用传的是一个结构副本,传指针是可以对原始结构进行操作
process(think); //如果think是一个函数,第一个是传函数的地址作为参数,第二个是传入think函数返回的值
process(think());
double pam(int); 这个函数原型,他的函数指针意思是pam是个函数,用一个指针指向该函数。double (*pf)(int)
*pf(int)意味着pf()是一个返回指针的函数
(*pf)(int) 意味着pf是一个指向函数的指针
double *estimate(int lines,double(*pf)(int)) 该函数原型意味着estimate函数返回一个double指针,第二个参数是个函数指针,这个函数指针指向的函数有一个int的参数,返回double值也即estimate函数第二个参数传入的是个double值而不是double指针
*pd[3] 一个序列,该序列有3个指针,不会看就加个char,char *pd[3],*自动和char结合,说明每个元素是char指针
(*pd)[3] 一个指针序列,该序列有3个元素
这里pd和&pd的值相同,但是类型不同(步长不同)
const double *(*pa[3])(const double*,int)
这样说:pa是一个包含3个指针的数组,每个指针指向这样的函数,该函数参数是double指针和int,返回const double*的值
对于内联代码,程序无需跳到另一个位置执行完在跳回来,所以运行速度快,在函数声明和定义前加上inline即可
如果一个类没写public和private,其他函数访问不了成员变量,因为默认是private
i+=6;
i+=7;那么c++会有个优化直接改成i+=13;如果不想让编译器这样优化可以初始化i时候给写成volatile int i=0;
引用就是该对象的别名,所以传参传的是一个数的引用,该函数交互两个数是可以交换的,并不是副本机制
引用作为函数的参数,没有出栈入栈操作,所以效率更高
也即用const修饰函数名,那么用了const修饰还不行,还要后面再加个const
;;a=1;这里是让全局变量a=1
如果类成员有指针,需要自己实现拷贝构造函数,否则存在浅拷贝风险
引用和指针的区别:
★ 相同点:
1. 都是地址的概念;
指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。
★ 区别:
1. 指针是一个实体,而引用仅是个别名;
2. 引用使用时无需解引用(*),指针需要解引用;
3. 引用只能在定义时被初始化一次,之后不可变;指针可变;
4. 引用没有 const,指针有 const,const 的指针不可变;
6. “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
7. 指针和引用的自增(++)运算意义不一样;
实际上“引用”可以做的任何事情“指针”也都能够做,为什么还要“引用”这东西?
答案是“用适当的工具做恰如其分的工作”。
指针能够毫无约束地操作内存中的如何东西,尽管指针功能强大,但是非常危险。
就象一把刀,它可以用来砍树、裁纸、修指甲、理发等等,谁敢这样用?
如果的确只需要借用一下某个对象的“别名”,那么就用“引用”,而不要用“指针”,以免发生意外。
如果字符串的深复制,一个值一个值的复制,那么记得另一个字符串最后加上' \0'
一个类初始化或者当做参数传递时候会自动调用构造函数,那么效率低,所以用引用好
这是explicit的用法
输出为1 1 1 1 。。。。
输出为1 2 3 。。。10
如果是C代码中的函数,在C++中使用一定要用extern“C”关键字来说明