memcpy
void * memcpy ( void * destination, const void * source, size_t num );
二进制拷贝
strcpy
char * strcpy ( char * destination, const char * source );
不能用于string,可用于char *和char []
strcat
char * strcat ( char * destination, const char * source );
Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a new null-character is appended at the end of the new string formed by the concatenation of both in destination. Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.
C风格字符串、字符数组、string
char *str1 = "Hello"; //只可通过str1[]读取字符,不可以更改 sizeof大小:4 strlen大小:5
char str2[] = "Hello"; //可以通过str2[]读取、更改字符 sizeof大小:6 strlen大小:5
string str3("Hello"); //可以通过str3[]读取、更改字符 sizeof大小:32,类似vector容器,预分配空间,可以动态增长。 不可作为strlen参数。
注意:sizeof计算的时候的不同点:指针的大小,字符数组的大小,string的大小。
sizeof计算的时候把最后的'\0'也计算,但是字符长度strlen不计算空字符。
指针常量、常量指针
指针常量不能指向内存中的另一位置。int * const p;
常量指针为指向常量的指针。不可通过它改变所指数据,但可以将它指向内存中其他位置。const int *p;
头文件的作用
现在有文件:file1.cpp file2.cpp file3.cpp,file2和file3都include file1.cpp,那么,如果file1.cpp文件被修改,那么所有include file1的文件,都必须要重新编译,如file2.cpp和file3.cpp。
如果有了file1.cpp对应的头文件file1.h,file2.cpp和file3.cpp都include file1.h,那么,如果file1.cpp被修改,则只需要重新编译file1.cpp单个文件。其他文件都不必重新编译。
无名对象和临时对象
无名对象,直接调用构造函数生成。如,Student& st = Student("Liang Liang"); 无名对象和临时对象不同,无名对象和普通定义的对象具有同样的生存周期。所以,可以适当的作为函数参数,初始化引用等用途。
临时对象,则在语句结束后即被销毁。使用时候需要特别注意。
变量和指针的组合声明
int* a, b, c;
只有a是int *指针类型,b、c均为int变量。
指针初始化
全局指针变量的默认初始值是NULL。而对于non-static局部指针变量p,必须显示的指定其初值,否则p的初始值是不可预测的,并不是NULL。所以,不管指针变量是全局的还是局部的,是静态的还是非静态的,应当在声明的同时,进行初始化。要么赋予它有效的地址,要么置为NULL。
多维数组、一维数组
声明数组时必须指定数组的大小。指定大小方法有二:一是显示指定,如int a[10];,二是隐式指定,如int b[] = {1,2,3,4,5,6};,编译器根据初始值个数自动计算数组大小。除此之外,两种方法可以结合,如int c[10] = {1,2};,数组大小为10,初始值个数小于数组大小,后面的元素被初始化为0。
当数组作为函数的形参:虽然在形参表中被声明为数组,但在函数内部,总被转化为合适的指针。一维数组被转化为元素类型的指针,二维数组被转换为指向一维数组的指针,以此类推。在函数体内,对其sizeof的结果为机器字长,32位机器为4。形参表中,如果是多维数组,必须指定除第一维外所有维的元素个数。
当数组不作为函数形参的时候,sizeof(数组名)的结果,是 数组长度*数组元素大小。
数组传递默认的是地址传递。如果想进行值传递数组,可以把数组封装到struct或者class。
动态分配的多维数组的删除和一维数组一样,采用delete[] array_name;。不需要更多的[]符号。因为编译器总是会将数组的大小存放在某个地方,以便删除的时候去读取。
可执行程序组成
可执行程序由指令、数据、地址组成。当CPU访问内存单元时,不论是读取还是写入,首先必须把内存单元的地址加载到地址总线(AB)上,同时将内存电路的读写控制设置为有效,然后内存单元中的数据就通过数据总线(DB)“流”向了接受的寄存器中,或者反向从内存流向寄存器。此即,内存读写的周期。
reinterpret_cast
The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types. 比如,用于int*和char*的转化,无符号整形unsigned int 和指针之间的转化。等等。
记住,void*转化为int*等,需要用static_cast。
C风格构造类型对象、数组构造和析构
C风格构造类对象一般指struct结构体,C风格中struct不支持成员方法。所以C中又称为POD:Plain Old Data。对于它对象的初始化可以采用一种特别的方法。如,Student st = {"WangBaoCai"}; 对象中其他的成员字段初始化为0(泛指的0,有默认构造函数的对象采用默认构造函数)。也可以在大括号中指定所有的成员初值。POD对象中不能定义成员方法,包括构造函数和析构函数。一旦定义了成员方法,它就不再是POD类型,也就不能采用上述初始化的特别方法了。
定义数组时候,数组成员的初始化:内置类型不初始化,数组元素的值为为定义,或者说是随机值。对象类型的采用默认构造函数初始化,数组元素类型必须提供默认构造函数,不然得显式提供初始化式。数组到达末尾作用域,析构的时候从数组末端元素开始析构。
结果:
private成员的访问
现有Base类,含有private成员string str,在其public成员函数fun(Base& b)的方法体中,可以直接访问private成员:b.str。
非法的拷贝构造函数
class A中的拷贝构造函数必须为A(const A& a),或者去掉const。绝对不能写成A(A a),因为这将导致无限的递归调用拷贝构造函数中,所以C++编译器在编译时会提示错误:错误的构造函数类型。