C++Primer 第一章和第二章简要

main函数

main函数是程序的入口,main函数的结构和其他的函数没有区别,但是,返回值必须是int,返回值为0,用0来表示执行成功,非0来表示其他;注意:main函数不可以重载;系统规定main的返回值为int,同时对于int值的返回,0是约定,但是也可以返回别的值;

输入输出
C++没有定义任何输入输入语句,例如像Java那样的InputStream,OutputStream,Writer,Reader类,使用的标准库,C++使用iostream库,该库包含istream,ostream,分别表示输入流,输出流;流可理解为字符序列,与istream对应的对象为cin,ostream对应的cout,cerr用来表示输出警告和错误消息,clog用来表示一般性信息,日志等;

    use namespace std;
    cout << "hello world";
    int number;
    cin >> number;

<<为输出运算符, >> 为输出运算符。这里的<<运算符可以理解为一个函数,cout需要接受两个对象,一个是ostream对象,另一个是要打印的值,可以理解为运算符函数:operator << (ostream os, Type type)。

命名空间

可以必满名字定义的冲突,标准库函数的所有名字都在命名空间std中,可以理解为指明该名字所在的区域;使用::作用域运算符指出定义在命名空间中的名字cout

std::cout << "hello world";

注释

单行// ;多行/*---*/;多行注释不能嵌套。

数据类型

数据类型是定义了一组操作和值的范围;

基本内置类型:分为算术类型和空类型,算术类型包含字符,整形,布尔,浮点。注意空类型不代表任何值;算术类型又分为有符号和无符号两种,有符号的可以表示正,负,0。无符号类型则表示大于等于0.。

类型转换

注意只有同种类型的数据才可以转换,例如算术类型,

bool b = 66; //非零为真(1),  
int i = b;   //i的值为1 ;
i = 4.345;    //i的值为4
double pi = i;   //pi的值为4.0 
unsigned char c = -1;   //c的值为255    对一个无符号类型赋值超出他的表示范围,结果是初始值对无符号类型表示数值总数取模后的余数。
signed char c2 = 256 ;    //c2的值是未定义的,程序可能崩溃|继续工作|生成垃圾数据

字面值常量

字面值常量的形式和值决定了它的数据类型;包括整型,浮点型,字符,字符串,布尔,指针字面量;

变量

变量代表的是一个存储空间,使用前必须先定义,定义的时候会被初始化,初始化不是赋值,初始化是在创建变量的时候赋予一个初始值,而赋值是把对象的当前值擦除,代替新的值;如果在定义的时候没有被初始化,则会进行默认初始化。内置类型的变量没有显式初始化,则会被默认初始化为0,例外是:定义在函数体内部的内置类型变量将不被初始化,如果拷贝或访问此类值将引发错误。

变量的声明即值声明,因为有可能存在分离式编译,所以有可能变量的定义在变量的使用之后或者在别的文件,所以声明是为了让程序知道。注意变量只能被定义一次,但可以被多次声明;

标识符

数字,字母,下划线,数字不能开头。

名字的作用域

即定义一个变量,所能被访问的有效边界,例如一个在函数中定义的变量,只能在函数中访问。

复合类型

引用:即给对象起另外一个名字,引用类型引用另外一种类型,int a = 12; int &b = a;相当于对a变量的内存空间奇起别名,然后对b的修改,也会修改a。

指针:内存单元,指向另一种类型,指针无需在定义的时候赋初值。 int a =14; int p = &a , 即p指向a。对指针的修改,也会影响原对象; 使用&来获取需要指向的对象的地址,使用\来进行指向对象的访问。 *p ;如果定义一个指针不知道他指向那,可以使用空指针,即int * a = NULL; 相当于 int *a = 0 ;

注意:一旦定义了引用,就无法在绑定其其他的对象,每次使用该引用都是最初的绑定对象;指针则没有限制;

int *p,a ; //注意: p是指针类型,a是int类型
int *p = &a;  //指向int类型的指针;
int **p2 = &p;  //指向指针的指针;
//不能定义指向引用的指针,指针是对象,但存在对指针的引用;
int * &m = p;
m = &a; //将a的地址复制给m;
*m = 0; //将a的值改为0;

const限定符

const修饰的变量的值不可以被修改;const修饰的变量,与非const修饰的变量比较来说,const也可以完成大部分操作 ,但不是全部,因为值不能被修改,所以例如,重新赋值就不行;注意const变量必须在定义的时候被初始化,因为之后就不可以被修改了。const默认只在文件内有效,对于多个文件中的const变量,会被认为是独立的变量,如果想多个文件共享一个const变量,只需要使用extern即可,这样只需要定义一次就行。

const修饰变量

const int a = 123;  //a 值不能再被修改;

const修饰引用

const int ci = 1023;
const int &t = ci;  //修饰引用
const int cc =12;
t = 123;  错误,因为t是对常量的引用
&t = cc ; 错误,因为引用只要被初次绑定,便不能被修改,与const修饰无关;
int &rr = ci ; 错误,因为试图让一个非常量引用指向一个常量引用;

注意:对常量的引用不能被用作修改它所引用的对象,如果可以修改,则会修改常量的值,与规定相悖;引用的类型必须与其所引用的类型一致,例外就是在初始化常量引用时允许任意表达式作为初始值,只要该表达式的结果可以转换成引用的类型即可。

const修饰指针

指针常量:指向常量的指针不能用于改变其所指对象的值;

const int number = 10;
const int * ptr = & number;

常量指针:指针本身定义为常量,必须初始化,且一旦被初始化,则它的值(即存放在指针中的那个地址)就不能被改变;

int number = 12;
int * const curr = &number;   //常量指针

常量指针指的是该指针是一个常量,它保存的地址不可以改变,即不可以改变其指向,但是其指向的指针的内容是可以改变的。

常量表达式

值不会改变,在编译期间就可以得到计算结果的表达式;注意:常量表达式,首先必须是常量,字面值也属于常量表达式,用长岭啊表达式初始化的const对象也是常量表达式。

可以声明变量为constexpr类型,这样变量一定是常量。

类型别名

因为有些类型复杂,所以可以使用简单的别名,两种方式:

使用typedef关键字:

typedef double dd;  

dd number,page;

使用别名声明:

using dd= double;

dd number,page;

注意:对于符合类型或常量,对其使用别名,会产生误会;对于一个使用类型别名的声明语句时,不可以直接将类型别名替换成它本来的样子;

typedef char * ptr;
const ptr cstr = 0;    // 指向char的常量指针;
const ptr *ps ;  //是一个指向char的常量指针;

decltype类型指示符

作用是选择并返回操作数的数据类型。

decltype(f()) sum = x;   //sum的类型是函数f的返回类型
const int ci = 0 ;
decltype(ci) x = 0;  //x的类型是const int

如果decltype中的表达式不是一个变量,则decltype返回表达式结果对应的类型。

头文件保护符

头文件中一般存在的是类的声明;为了防止头文件被包含多次,引入头文件保护符;使用预处理器来技术。头文件保护符依赖预处理变量,预处理变量有两种状态:已定义和未定义。

#define命令:把每一个名字设定为预处理变量,

#ifdef:当且仅当变量已定义时为真;

#ifndef:当且仅当变量未定义是为真;

#endif: 指令结束符;

#ifdef xxx   //如果为假,即没有定义某个变量
#define  xxx  //引入头文件
...
#endif