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