`

《C++ Primer》学习笔记

阅读更多

 

数组与指针:

数组的长度必须用大于等于1的常量表达式(整型字面值常量,枚举常量,常量表达式初始化的整型const对象)定义,非const变量以及要到运行阶段才知道的其值的const 变量(const int sz=getSize();)都不能用于定义数组的长度。

字符数组

char ch1[]={‘c’,’+’,’+’};            //no null 长度是3

char ch2[]={‘c’,’+’,’+’,’\0’};            //explicit null 长度是4

char ch3[]={“C++”}; or char ch4[]=”C++”           //null terminator added automatically 长度是4char cha[3]=”c++”; 会报错。

动态数组的定义

int *pia=new int[10];    //如果是内置类型,无初始化,要初始化如下

int *pia=new int[10]();    //只能初始化为默认值,不能用初始化列表为数组元素提供各不相同的初值,由于常数组定义的时候就要初始化(就初始化为默认值,所以就没有太多意义)

允许动态分配空数组,在编译时并不知道数组的长度,例如

int *p=new int[n];      //这样即使出现n=0也可以通过,只是不能进行解引用。

如果必须分开定义指针和其所指向的对象,则将指针初始化为0。因为编译器课检测出0值的指针,程序可判断该指针并未指向一个对象。允许将数值0(从C语言继承下来的预处理变量NULLNULLcstdlib头文件中)或编译时值为0const量(值为0int型变量不能赋给指针)

string *psa=new string[10];    //如果类类型,使用默认构造器实现初始化

表示形式                         含义

a                                 二维数组名,0行首地址

a[0],*(a+0),*a                       00列元素地址

a+1,&a[1]                          1行首地址

a[1],*(a+1)                         10列元素a[1][0]的地址

a[1]+2,*(a+1)+2,&a[1][2]              12列元素a[1][2]的地址

*(a[1]+2),*(*(a+1)+2),a[1][2]           12列元素a[1][2]的值

 

&a[i]a+i指向行,而a[i]*(a+i)指向列,在指向行的指针前面加一个*就转换为指向列的指针,在指向列的指针前面加&,就成为指向行的指针。

char* string=”I love China!”;等价于char* string;    string=”I love China!”;

数组可以在定义时整体赋初值,但不能在赋值语句中整体赋值。

如: char str[14]={“I love China!”};

不能等价于

char str[14];

str[]={“I love China!”};

数组名虽然代表地址,但是它是常量,它的值不能改变的。

指向函数的指针的指针变量的一般定义形式为

数据类型 *指针变量名)(函数参数列表);

typedef 简化函数指针的定义

typedef bool (*function)(const string&);

该定义表示function是一种指向函数的指针类型的名字,该指针类型就是上面函数声明的原型,要使用该函数指针类型时,只需直接使用function即可,不必每次都把整个类型声明全部写出来,eg: function fp; bool length(const string &); fp=length; or fp=&length;

函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值。

给函数指针变量赋值时,只需要给出函数名不必给出参数,例如:

p=max;     不能写成 p=max(a,b);

通过指针调用函数,可以不需要解引用操作符,直接通过指针调用函数,例如:p(1,2)当然也可以解引用。

函数指针形参两种形式:

void usePointer(const string &, const string &,bool(const string &, const string &));

or

void usePointer(const string &, const string &,bool(*)(const string &, const string &));

返回指向函数的指针

int (*ff(int))(int*,int);

理解上面的含义:ff(int)是一个函数,函数返回int(*)(int *,int)的一个指向函数的指针,使用typedef可使该定义更简明易懂,如下,

typedef int (*PF)(int*,int);

PF ff(int);

阅读函数指针声明的最佳方法时从声明的名字开始由里到外理解

指向重载函数的指针

指针类型必须与重载函数的一个版本精确匹配,如果没有精确匹配的函数,则对该函数指针的初始化或赋值将导致编译错误

eg: void ff(vector<double>);  void ff(unsigned int);

void (*fp)(unsigned int)=ff;     //ok

void (*fp)(int)=ff;       //error

 

指针数组和指向指针的指针

int* p[4];             //由于[]和()*优先级高,故这显然是数组形式,有四个元素,元素类型是指针类型

in(*p)[4];             //这是指向一维数组的指针变量,这个数组有四个指针元素

初始化

初始化是指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并通新值代替。有两种初始化方式:复制初始化 int ival(1024);和直接初始化 int ival=1024;

内置类型的变量的初始化

内置类型变量(没有初始化)在函数体外定义的变量系统都初始化成零,在函数体里定义的内置类型变量不进行自动初始化。

类类型变量的初始化

类类型变量不管在哪里定义,默认构造函数都会被使用,如果不存在默认构造函数,又没有显示的初始化,没有初始值是不可能定义这种类型的变量的,所以会报错。

数组的初始化同样要看元素还是要分内置类型还是对象

变量的定义用于变量为变量分配存储空间,还可以为变量指定初始值。声明用于想程序表明变量的类型和名字,定义也是声明。可以通过extern关键字声明变量名而不定义它,不分配存储空间。

引用与const

const 和引用一样变量必须在定义时初始化,若是类中的const数据成员,则只能通过构造函数的参数初始化表对其进行初始化。

const变量对象默认为文件的局部变量,此变量只存在于那个文件中,不能被其他文件访问。非const变量默认为extern,要使const变量能够在其他的文件中访问,不行先是指定它为extern

不能建立引用的数组,例如:char c[10]=”world”;char &ch[16]=c;   //这是错误的。

可以将变量的引用的地址赋给一个指针,例如: int a=3;   int &b=a;   int *p=&b;

但不能写成 int& *p=&a;不能建立指向引用类型的指针变量

可以建立指针变量的引用,例如:int i=5;   int *p=&I;   int* &pi=p;

可以用常量或表达式对引用进行初始化,但此时必须用const作声明,例如:

int i=10;

const int &a=i+1;

编译系统会生成一个临时变量,用了存放表达式的值,引用时该临时变量的别名。系统将const &a=i+1转换为 int temp =i+1; const int &a=temp;这种方法还可以用于不同类型的变量对之初始化(能复制兼容的类型)例如:

double d=3.1415926;

const int &a=d;

系统转换为 int temp =d;为了防止歧义性,没有添加const是不能通过的。

总之,非const引用只能绑定到与该引用同类型的对象上,const引用则可以绑定到不同但相关的类型的对象或绑定到右值。

指向const对象的指针

const double *cptr;

把一个const对象的地址赋给一个普通的、非const对象的指针会导致编译时的错误。不能使用void*指针保存const对象的地址,必须使用const void* 类型的指针报错const对象的地址。

允许把非const对象的地址赋给指向const对象的指针,但这时不能通过这个指针修改非const对象的值。

const指针

int temp=10;

int *const ptr=&temp;

void*指针表明该指针与一地址值相关,不能使用void*指针操作它所指向的对象;void*指针只支持几种操作:与另一个指针进行比较;向函数传递传递void*指针或从函数返回void*指针;给另一个void*指针赋值。

String

cin读取并忽略开头的空白字符,并再次遇到空白字符读取终止。

getline并不忽略行开头的换行符,如果第一个字符就是换行符,则string参数将被置为空stringgetline遇到换行符就返回,换行符不会存在在string对象中。

+”操作符,使用该字符串面值的链接必须至少有一个是string类型,例如:

string s=”hello”+”sb”;

string s=”sb”+”woshi”+s1;    //这两行都是错误的

 

sizeof 表达式结果是编译时变量

 

this指针

在普通非const 成员函数中,this的类型是一个指向类类型的const指针,可以改变this的指向对象的值,但不能改变this所保存的地址。在const成员函数中,this的类型是一个指向const类类型对象的const指针。

const对象只能使用const成员,非const对象没有这个限制。可以使用const来重载成员函数。构造函数不能声明为const

成员初始化的次序

成员被初始化的次序就是定义成员的次序,而构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的顺序。

隐式类类型的转换

Book(const string &bookID=””){};   //定义了从stringBook

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics