您的位置:首页 > 编程语言 > C语言/C++

C++Primer(中文第五版)学习笔记(第1天)

2018-03-28 22:23 211 查看

变量

int a=0;
int a={0};
int a{0};
int a(0);
无论初始化对象或是为对象赋值。但注意不允许初始值存在丢失风险:

double pi=3.1415;
int b={pi};
定义于任何函数之外的内置类型变量被初始化为0,函数体内部(包括main函数!!)的内置类型变量不被初始化。

C++支持分离式编译,即程序若干文件可被独立编译。

C++是一种静态类型语言,其含义是在编译阶段检查类型。

声明使名字为程序所知,定义负责创建与名字关联的实体。若想声明一个变量而非定义它,则在变量前添加关键字extern,否则为声明并定义—若给extern关键字标记的变量赋初值,则extern无用。

extern int i;
//声明i而非定义i
int j;
//声明并定义j
int a=0;
//显示初始化即成定义
在函数体内部,若试图初始化一个由extern关键字标记的变量,将报错。

变量能且只能被定义一次,但可以被多次声明

用户自定义的标识符(变量名)不能连续出现两个下划线,不能以下划线紧连大写字母开头,定义在函数体外的标识符不能以下划线开头。

全局(静态)变量名与局部变量名相同,局部作用域内使用局部变量。

引用与指针

引用即为对象起别名,引用类型引用另外一种类型。引用与初始值对象一直绑定在一起,而非拷贝初始值。

int a=0,&i=a;


注意引用类型要和与之绑定的对象严格匹配,且只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起,以下为错误定义

int &a=3;
double b=3.14; int &a=b;
int &a
引用本身并非一个对象,一旦定义了引用,就无法再绑定到另外的对象,之后每次使用这个引用都是访问它最初绑定的那个对象。

指针*p与引用&a区别:

1. 指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。

2. 指针无须再定义是赋初值。

取地址符&b与解引用符*p:

int b=1,*p=&b;
//取地址
int *p=0;cout<< *p;
//解引用
&随类型名出现,a是一个引用。&出现在表达式,b是一个取地址符。

不能定义指向引用的指针,因为引用不是对象,没有实际地址。

指针的类型必需与指向对象的类型匹配,否则报错。

不能把变量直接赋给指针,即使变量值等于0!

解引用操作仅适合于那些确实指向了某个对象的有效指针

指针的值(即地址)4个状态:

1. 指向一个对象

2. 指向紧邻对象所占空间的下一个位置

3. 空指针,意味着指针没有指向任何对象

4. 无效指针,即上述3种之外的其它值,不得拷贝或访问

第2种和第3种行为下的指针同样不允许试图访问。

空指针

int *p=nullptr;
int *p=0;
int *p=NULL;
//需要cstdlib库(?存疑,一般没有也能用)
这里nullptr是一种特殊类型的字面值,它可以被转换成任意其它的指针类型。NULL为预处理变量,值为0。

预处理变量由预处理器负责管理,预处理器是运行与编译过程之前的一段程序,当用到一个预处理变量时,预处理器会自动地将它替换为实际值。预处理变量无视作用域规则!

任何非空合法指针对应的条件值都是true。

void* 指针了存放任意非const类型任意非常量对象的地址,但不能直接操作void*所指向的对象,必须强制类型转换。

引用不是对象,故而不能定义指向引用的指针。但指针是对象,故存在对指针的引用:

int p,&r=p;
//表示r是一个对指针p的引用

int i=36; r=&i;
//表示r引用了一个指针,此处即为令p指向i

*r=0;
//解引用得到i,即p指向的对象,将i的值改为0

const限定符

const对象一旦创建后其值就不能再改变,所以const对象必须初始化,但初始值可以为任意复杂的表达式,比如:

const int i=get_number();


注:const对象能完成大部分非const对象所能参与的操作,主要限定在于不能改变其内容。例如const int和普通的int一样都能参与算术运算,也都能转换成一个布尔值,赋值给其它变量(不论是否为常量)。

编译器在编译过程中把用到常量的地方都替换成对应的初始值!

若想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字。

// file1.cpp 定义并初始化一个常量

extern const int s=get_number();


// file2.h 访问了常量

extern const int s;
//与file1.cpp中定义的s是同一个

把引用绑定到const对象上,称之为对常量的引用

const int a=1;


const int &b=a;
//正确,引用及其对应的对象都是常量

b=4;
//错误,对常量的引用不能修改它所绑定的对象

int &c=a;
//错误,试图让一个非常量引用指向一个常量对象

初始化常量引用允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。这意味着,允许一个常量引用绑定非常量的对象、字面值、甚至一般表达式:

int i=4;


const int &a=i;
//允许将const int &绑定到一个普通int上,但a不允许修改i的值!i可以修改自己的值

const int &b=4;
//正确

const int &c=a*2;
//正确

int &d=v;
//错误,非常量引用不能赋值常量引用

注:

double j=3.14;


const int &e=j;
//能运行,double可以转换成int类型。但非法

这里为了确保让e绑定一个整数,编译器把上述代码变成了:

const int temp=j;
//由double生成一个临时的整型常量

const int &e=temp;
//让e绑定这个临时量

注意此时e绑定的是一个临时量而非j!

指向常量的指针(const int *p)与指向常量的引用用法规则相同。

常量指针是把*放在const关键字之前,这时指针是一个常量,不变的是指针本身的值(即指向的地址),而非其所指向的对象的值保持不变。能否通过指针(*p)修改其所指向的对象的值完全取决于所指向对象的类型(即是否为非常量)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: