学习一门编程语言要理解语法特征的实现细节
* 内置类型
* 变量 用来为对象命名
* 表达式和语句 操纵上述数据类型
* if while 控制结构
* 函数
* 扩充:两种机制*
1. 程序员自定义数据类型
2. 封装成库函数供程序员调用
C++是静态数据类型语言,类型检查发生在编译时
数据类型是程序的基础:他告诉我们数据的意义和可以执行的操作
基本内置类型
2.1.1 算数类型
整形 浮点型
* 大多数机器字节由8bit 构成 字32或者64bit也就是4或者8字节
* 明知不为负选无符号型
* 如果数值超过int 用long long
* 算术表达式不要有char bool,只有存放字符或者布尔值时才用
* 执行浮点型用double
2.1.2类型转换
对象的类型定义了对象能包含的数据和能参与的计算
bool b=42; //b true
int i=b; //i=1
i=3.14; //i=3
unsiged char c=-1;//c=255,假设char8bit
* 赋给符号型一个超出他范围的值,结果是未定义的
* 赋给一个无符号型超出范围的值,则对这个无符号型能表示的数字个数取余,如8bit unsigned char 能表示0-255共256个,大于255的数字应对256取余
*程序应尽量避免依赖于实现环境的行为
* 含有无符号类型的表达式 切勿混用符号类型与无符号类型,因为带符号数会转化为无符号的
* 字面值常量
* 20 十进制
* 024 八进制
* 0x14 十六进制
* short没有字面值
* 字符、字符串字面值
* 字符串字面值实际上是由常量字符构成的数组
变量
变量提供一个具名的、可供程序操作的存储空间。c++中每个变量都有其数据类型
。数据类型决定变量所占空间大小和布局方式、该空间能存储的数值的范围以及科技参加的运算。
*对象:她是一种能存储数据并具有某种数据类型的内存空间
在c++中初始化与赋值不同,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象当前值擦除,而以一个新值来代替
1. 列表初始化时如果存在丢失信息的风险,则编译器将报错,并拒绝执行
2. 定义变量么有初始化将执行默认初始化,默认值与类型和定义变量的位置有关
3. 定义与函数之外的变量如果是内置类型初始化为0,定义在函数体内部的内置类型将不被初始化,一个未被初始化的内置类型变量将不被初始化,试图拷贝或其他形式访问将出错
为了支持分离式编译,c++将声明和定义分开,声明使得名字为程序所知,一个文件想使用别处定义的变量必须包含对那个名字的声明,而定义负责创建于那个名字关联的实体
声明:变量声明规定了名字和类型
定义:定义也包括这些,但另外还要申请存储空间,还有可能为变量赋一个初始值
使用变量之前必须声明,C++是一个静态类型,也就是编译期阶段检查类型
**变量命名规范:
1. 标识符要能体现实际含义
2. 变量名一般用小写字母开头
3. 用户自定义类名一般以大写字母开头
4. 若有多个单词组成,则单词间应有明显的区分**
名字的作用域
c++中大多数作用于都已花括号分隔;同一个名字在不同的作用阈可能指向不同的实体
名字的有效作用域始于名字的声明语句,以声明语句所在的作用与末端为结束
引用必须初始化:她是为已经存在的对象起了另一个名字,不能定义引用的引用;引用只能绑定在对象上,而不能字面值或与某个表达式的计算结果绑定
指针:
* 指针是指向另外一种类型的复合类型,与引用类似,指针也实现类对其他对象的间接访问。
与引用的不同点
1. 本身就是对象,允许对指针赋值和拷贝,而且在指针的生命周期里可以先后指向几个不同的对象
2. 指针不用必须定义时赋初值。与内置类型一样在块作用域定义的指针如果没有初始化也将有一个不确定的值,
指针值
1. 指向一个对象
2. 指向紧邻对象所占空间的下一个位置
3. 空指针 意味着没有指向任何对象
4. 无效指针,上述情况之外的指针
试图访问无效指针与试图使用未经初始化的变量是一样的,后果无法预估;2 3指针是有效的但是用同样受到限制,显然他们没有指向任何具体对象,不允许访问
空指针:nullptr,生成空指针的方法:
int * p1=nullptr;
int *p2=0;
建议:初始化所有指针
void*指针:是一种特殊的指针类型,可用于存放任意对象的地址,但是不知道该地址中到底是什么类型的对象 ,所以不能才做她指向的对象。任何非常亮对象的地址都能存入void *;
理解复合类型的声明:
变量的定义包括一个基本的数据类型和一组生命符,同一条语句中,虽然基本数据类型只有一个,但声明符的形式可以不同。一条定义语句可能定义出不同类型的变量:
int i=1024.*p=&i,&r=i;
const引用两个列外:1.可以引用表达式,只要该表达式能转化成引用的类型即可。2.const引用可以引用非const对象
指针与const
1.指向常量的指针不能用于改变其所指向对象的值,存放常量对象的值必须使用指向常量的指针;2.与常量引用一样,也没有要求所指向对象必须是一个常量(可以通过其他途径修改值,只是不能通过const指针和const引用修改而以
const指针:指针本身是常量;
指针是一个对象,因此他本是是不是一个常量与她所指向的对象是不是常量是两个独立的问题。用顶层const表示指针本身是个常量,而用名词底层const表示所指对象是const
对于copy时,是顶层const还是底层const区别明显:
对于顶层const考入考出的对象是否是常量都没什么影响:
int i=0;
int *const p1=& i;//不能改变p1的值,这是一个顶层const
const int ci=42;//不能改变ci,顶层。。
const int * p2=& ci;//允许改变p2,底层const
const int * const p3=p2;//
const int &r=ci;//用于声明引用的const都是底层const
i=ci;//正确,copy ci 的值,它是顶层const
p2=p3;//right 他们指向的类型相同,顶层部分不影响
低层const拷贝时不能忽视,考入考出时对象必须具有相同的底层const资格,或者两个对象的数据类型可以转换,一般非常量可以转成常量,反之不行
int * p=p3;//错误,p3包含底层const,而p 没有】
p2=p3;//zhengque
p2=& i;//正确int* 能转化成const int *
int &r=ci;// 错误,普通int&不能绑定到int常量
const int &r2=i;//z正确,const int& 可以绑定到一个普通int
auto与复合类型。常量
1.编译器推断出的类型有时候和初始值不同,编译器适当改变结果使其符合初始化规则
2. 使用引用是使用的引用的值,所以引用作为初始值时,auto得到的结果是印度用的对象的值的类型而不是引用
3. auto一般忽落掉顶层const,保留地层const
4. 如果想得到顶层const要明确说明:const auto f=ci;//(ci是const int ci=i;推演类型为int),f是constint
5. 可以将引用类型设定为auto,原来初始化规则仍然适用
auto &g=ci;//g是一个正型常量引用,绑定到ci
auto &h=42;//错误,不能为非常量引用绑定到字面值,
常量表达式:指值不会改变编译过程就能得到结果的表达式
constexpr:如果认定一个量是常量表达式就把它声明为constexpr
;算术类型。引用、指针都是字面值类型;自定义类则不是
**指针和constexpr,在constexpr声明中如果定义了一个指针,限定符仅对指针有效,与所指对象无关
类型别名:两种方法
1.使用关键字typedef typedef double wages;//wages是double的同义词。
2. 使用新的别名声明: using SI=Sales_item;//SI是Salesman_item的同义词
auto类型说明符(显然auto定义的变量必须有初始值)
、auto item =val1+val2;//item初始化为val1与val2相加的结果。
一条声明语句只能有一个基本的数据类型
对常量对象取地址是一种底层const
要在一条语句定义多个变量,切记,&和 * 只是从属于某个声明符,而非基本数据类型的一部分,初始值必须是同一种类型
decltype类型指示符:希望从表式类型推断出要定义变量的类型,但不使用表达式的值作为初始值,此时可以用这个指示符;
decltype(f()) sun=x;//sun 的类型就是函数f()返回的类型
引用从来都以其对象的同义词出现,只在decltype是个例外(用其来推断类型)
她处理顶层const和引用的方式与auto有些许不同。如果decltype使用的表达式是一个变量,则返回该变量的类型(包括顶层const和引用在内)
例如:
int i=0, &r=i;
auto a=r;//a是一个整数(r是i的别名,i是一个整数)
const int ci=0,&cj=ci;
decltype(ci) x=0;//x是一个const int
decltype(cj) y=x;、//y的类型是 const int &,y绑定到变量x
decltype(cj) z;//错误,z是一个引用,必须初始化
decltype和引用
如果decltype使用的表达式不是一个变量,则返回表达式结果对应的类型
int i=42,*p=&i, &r=i;
decltype(r+0) b;// right r+0结果是一个int,而不是引用
decltype(*p) c;//错误,c是int&,必须初始化
如果表达式的内容是解引用操作,则decltype将得到引用类型
decltype((i)) 双层括号得到的永远是引用,而decltype(variable) 结果只有当variable本身是一个引用时才引用
自定义数据类型
一般来说最好不要把对象定义和类定义放在一起
预处理器可以确保多次包含仍能安全工作,它是编译执行之前的一段程序
还可用头文件保护符 #define、 #ifdef 、#ifndef 、#endif
`
#ifndef 。。
#define ..
…..
…..
#endif