C++/C小知识
1.sizeof strlen
1> 大部分编译程序在编译时会把sizeof计算过了,是类型或者变量的长度,这就是sizeof(x)可以用来定义数组维数的原因,strlen的结果要在运行的时候后才计算出来。
2> 数组做sizeof的参数不退化,传递给strlen就退化为指针了;
3> sizeof()括号中的内容在编译过程中是不被编译的,只是被替换类型,如 int a = 8;sizeof(a)在编译过程中,被替换成sizeof(int),如果sizeof(a=6),此后a的值还是8,是不变的。
4>
char* b = "we are best!"; char dat[] = {'a','r','t','y','i'}; int e = sizeof(dat); // e = 5
int g = strlen(dat); //g=17 为什么呢??? int a = sizeof(b); // a = 4,指针占4个字节 int c = sizeof(*b); // c = 1,指向第一个字符 int d = strlen(b); // d = 12 ,不包括\0
2. 一个空类占用空间1,多重继承的空类所占用的空间也是1,虚拟继承设计到虚表(虚指针),它要占用空间大小为1。
3. 引用总是指向在初始化时指向的对象,以后不能改变。声明一个引用的时候必须同时对其进行初始化。
4. char c[] = "hello world";//分配一个局部数组,局部变量,对应内存中的栈
char *c = "hello world";//分配一个全局数组,全局变量,对应内存中的全局区域(静态存储区)只读
5. void *realloc(void *mem_address, unsigned int newsize);//指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。//新的大小一定要大于原来的大小,不然的话会 导致数据丢失!头文件#include <stdlib.h> 有些编译器需要#include <malloc.h>。
6. 类的静态成员变量应赋初值。
7. 类的构造函数的初始化列表的初始化变量的顺序是根据成员变量的声明顺序来执行的。
8. 类中,常量必须在构造函数的初始化列表里面初始化或者将其设置成static。
class Test { static const int num=2; //A(){const int num = 2;} };
9. C++多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写。(这里我觉得要补充,重写的话可以有两种,直接重写成员函数和重写虚函数,只有重写了虚函数的才能算作是体现了C++多态性)。多态性可以简单概括为“一个接口,多种方法”,多态实现了接口重用。而重载则是允许有多个同名的函数,而这些函数的参数列表不同,允许参数个数不同,参数类型不同,或者两者都不同。编译器会根据这些函数的不同列表,将同名的函数的名称做修饰,从而生成一些不同名称的预处理函数,来实现同名函数调用时的重载问题。但这并没有体现多态性。重载不是一种面向对象的编程,只是一种语法规则。
重载函数必须参数个数或者参数类型不一样,不可以只是返回类型不一样。
10. 模板类的友元重载:
1 #include <iostream> 2 3 using namespace std; 4 5 template <class T> 6 class Test; // 模板类前置声明; 7 template<class T> 8 9 ostream& operator << (ostream& out, const Test<T>& obj); // 模板类友元前置声明; 10 template<class T> 11 12 class Test 13 { 14 15 public: 16 17 friend ostream& operator << <> (ostream& out, const Test<T>& obj); // 模板类友元定义,注意格式"<>"; 18 19 Test(T n=0):num(n){} 20 21 Test(const Test<T>& copy) 22 { 23 24 num = copy.num; 25 26 } 27 28 private: 29 30 T num; 31 32 }; 33 34 template<class T> 35 36 ostream& operator << (ostream& out, const Test<T>& obj) 37 { 38 39 out<<obj.num<<endl; 40 41 return out; 42 } 43 44 int main() 45 { 46 47 Test<int> t(2); 48 49 cout<<t; 50 51 return 0; 52 }
或者
1 #include <iostream> 2 3 using namespace std; 4 5 template<class T> 6 7 class Test 8 9 { 10 11 public: 12 13 template<class S> // 注意<class S>S 14 friend ostream& operator << (ostream& out, const Test<S>& obj); 15 16 17 Test(T n=0):num(n) {} 18 19 20 21 Test(const Test<T>& copy) 22 23 { 24 25 num = copy.num; 26 27 } 28 29 30 31 private: 32 33 T num; 34 35 }; 36 // 注意<class T>和<class S>都行 37 38 template<class T> 39 40 41 ostream& operator << (ostream& out, const Test<T>& obj) 42 { 43 44 45 out<<obj.num<<endl; 46 47 48 return out; 49 } 50 51 52 int main() 53 54 55 { 56 57 58 Test<int> t(2); 59 60 61 cout<<t; 62 63 64 return 0; 65 66 67 }
11. 类继承时,如果不指定public,C++默认是私有继承。
12. 如果p是指针,typeid(*p)返回p所指向的派生类类型,typeid(p)返回基类类型;
如果r是引用,typeid(r)返回派生类类型,typeid(&p)返回基类类型。
13. 在C++中,后缀++如果是成员函数,那么他就是二元操作符。
1 Class A 2 { 3 private: 4 int a; 5 public: 6 void operator++() 7 { 8 a+=1; 9 } 10 void operator++(int) 11 { 12 a+=2; 13 } 14 } 15 int main() 16 { 17 A a; 18 ++a;//这是一元操作 19 a++;//这是二元操作
return 0;
20 }
14. 移位运算是最有效的计算乘除法的运算之一。
15. 在unsigned short int 中无符号的-1等于65535。sizeof(unsigned short int)=2.
15. hex是以16进制输出数据,如cout<<hex<<i<<endl; %x 是输出16进制.\,%d输入输出为整形 。
17. 在类中的static成员函数属于整个类所拥有,这个函数不接收this恩,因而只能访问类的static成员变量。
18. 调用函数时首先进行参数压栈,一般情况下的压栈顺序是从右到左,最后压函数地址。
19. char值得范围是-128~127.
20. sprintf(s,"%d",123);//把证书123打印成一个字符串保存在s中。可替代itoa.
char* who = “I”; char* whom = “you”;sprintf(s,"%s love %s.",who,whom);//产生I love you.
21. 时间复杂度0(1)<0(logn)<0(n)<0(nlogn)<0(n^2)<0(n^3)<0(2^n).
22. 仅知道先序后序无法确定树的形态。
23. 运算符优先级:~/!/++/--/*/& > 算数运算符(* 、/、%大于+、-) > 移位运算符 > (<、>、>=、<=) > (==、!=) > & > ^ > |
> && > ||
24. 为了确保const对象的数据成员不会被改变,在C++中,const对象只能调用const成员函数。
25. 类的复制构造函数参数应为const A &,否则按值传递一直调用复制构造函数会导致栈溢出。
26. 静态方法只能用类的静态成员。
27. 指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
28. 构造函数可以抛出异常,析构函数不能跑出异常。
29. 函数的定义不可以嵌套,及一个函数中不可以定义另一个函数。
30. 不能重载的运算符:sizeof . .* :: ?: typeid cast
31. 字符串常量不可以修改,char* p2 = "world";不能这样*p2 = 'a';
要修改,这样定义字符串,char p2[] = "world";