c++primer 第二章 变量和基本类型

2.1基本内置类型

  • 基本数据类型有算数类型和空类型

2.1.1算术类型

  • 算术类型表
    c++primer 第二章 变量和基本类型_第1张图片

  • 内存最小可寻址内存块:字节(byte,大小为8bit);存储单元为4或8字节(32位机上32bit,64位机上64位)。

  • 有符号数范围0和正负数;无符号数范围0和正数。
    但是字符型需要注意,有三种声明方法:char,unsigned char,signed char
    unsigned 表示范围0和正数,signed char范围为正负数和0,char表示范围不确定,由编译器确定。

  • 注意类型选择

    1. 知道数值不可能为负数,用无符类型。
    2. 因为long一般和int表示范围相同,超过int范围,使用long long类型。
    3. 算数表达式中不要使用char和bool
    4. 浮点运算中使用double。因为float一般精度不够,duoble和float计算代价差不多。

2.1.2类型转换

  • signed char c= 256 //赋值超过范围
    赋值超过范围,结果未定义。程序可能继续运行、崩溃、也可能产生垃圾数据。
  • 避免编写依赖实验环境的代码,否则代码不可移植。如把int的大小看成固定已知值是错误的。
  • 避免混用有符号类型和无符号类型。
    有符号类型会自动转换为无符号类型。

2.1.3 字面值常量

20/*十进制*/     024/*八进制*/    0x24/*十六进制*/
0.  /*浮点数默认为double*/  
'a'   /*字符型 */      "a"/*字符串*/

c++primer 第二章 变量和基本类型_第2张图片

2.2 变量

2.2.1定义变量

  • c++11新标准,列表初始化使用{}初始化。如果初始化的值有丢失信息的危险,就会报错。
int a{3.14} //报错,有丢失信息的危险
  • 默认初始化:任何函数体之外的内置类型被初始化为0。
    定义在函数体内的默认类型未被初始化,其值未定义;类的对象没有被显式初始化,其值由类定义。

2.2.2 变量声明和定义的关系

  • 声明规定了变量类型和名字,定义还申请了内存空间。
    变量只能被定义一次,但可以被声明多次。
  • extern关键字
    • 只想声明,不想定义,使用extern
    • 若给extern标记的变量赋值,就抵消extern作用。赋值的extern变量,这既是声明也是定义。
    • 在函数内部,试图初始化一个extern标记的变量,会引起错误。
extern int a =3; //正确,既是声明也是定义
extern int b;	//正确,是声明
int mian(){
	//extern int c =3; //函数体内部,报错
	extern int d;//正确,是声明
}

2.2.3 标识符

c++关键字
c++primer 第二章 变量和基本类型_第3张图片

2.2.4 名字的作用域

名字的有效区域始于声明,终于作用域末端。

2.3 复合变量

2.3.1 引用

  • 引用必须被初始化,指向一个对象。
int &a =3;//错误,3不是一个对象
  • 引用本身不是一个对象,不能声明对引用的引用

2.3.2 指针

  • 指针本身是一个对象,指针指向一个对象。(不能定义指向引用的指针)
    c++primer 第二章 变量和基本类型_第4张图片
  • 空指针:
    过去程序中的NULL,是一个预处理变量,由预处理器负责。
    现在c++中引入nullptr。c++中最好使用nullptr。
  • void*
    作为函数输入输出
    与其他指针作比较

2.3.3 理解复合类型的声明

没讲啥。

2.4 const限定符

  • const 对象必须初始化。有运行时初始化和编译时初始化。
const int i = get_size();//正确:运行时初始化
const int j  = 42; //正确:编译时初始化
const int k;
  • const对象仅在文件内有效
    因为先编译后链接,所以const变量仅在一个文件内有效,多个文件中同名的const值等同于分别定义的不同变量。
    想要多个文件使用相同的const对象,可以添加extern关键字
    在这里插入图片描述

2.4.1 const引用

  • 对常量的引用。对常量的引用也要声明成const。
const int ci =1024;
const int &r1=ci;//正确
int &c2 =ci;//错误

2.4.2 指针和const

  • 指针的类型必须和所指对象一致。有两个例外。第一个是 一个指向常量的指针指向一个非常量。
double dval =3;
const double *cptr =&dval ;//指针指向可变,不可以通过指针改内容

2.4.3 顶层const

  • 顶层const和底层const
    • 顶层const:对象本身是常量,如果这个对象是一个指针,那么表示这个指针是一个常量;
    • 底层const:指针指向对象是一个常量。
    • 如果需要用引用或者指针表示底层const,必须加上const限制。
const int i=0;//i 是一个底层const
int &r = ci;//错误!!一个底层const的引用也必须是const
  • 区分指针常量和常量指针。
    *为界,若变量类型和const在前,表示指向对象不可修改;若const在*后,表示指针不可以指向其他对象。
const int ci = 0;
//ci = 1; //错误
int i = 0 ;
i = 1;

const int*ptr_down = &i; //等同于int const *ptr_down = &i
ptr_down = &ci; //正确,指针本身可以指向不同对象
//*ptr_down =2;//错误,不可以通过指针修改对象
	
int *const ptr_up = &i;
//ptr_up = &ci;//错误
*ptr_up =2;//正确

2.4.4 constexpr和常量表达式

  • 用constexpr申明的变量,编译器会在编译时检查是否是常量。
  • constexpr定义的指针,只对指针有效(一定一是个顶层const)
const int *p1 =&i;//p1指向整型常量
constexpr int *p2 =&i;//p2指向i,并且不能指向其他整数对象

2.5 处理类型

2.5.1 类型别名

  • typedef以及using的别名声明
typedef duoble wages;
using wages = double;
  • 类型别名不能靠替换来理解
typedef char * pstring;
//不同于const char * ctrs ;
//cstr是一个指向char的常量指针,不可重新指向其他变量
const pstring ctrs =0;
//ps是一个指针,可以指向cstr的类型
cnost  pstring *ps;   

2.5.2 auto类型说明符

  • auto定义的变量一定要有初始值
  • 在类型一致的情况下,auto可以声明多个变量;引用初始化使用的是引用对象的值。
auto i=0,&r=i;//正确
auto size =0,pi=3.14;//错误,类型不一致
auto a =r;//a是int类型
  • auto忽略顶层const,保留底层const。若需要保留顶层const,需要明确指出。

2.5.3 decltype 类型指示符

  • decltype类似auto,但是可以只声明类型,不指定初始值。
  • decltype返回变量的类型,包括顶层和底层const。
  • decltype和引用:若返回左值,decltype声明的变量需要初始值。
int i=42,*p=&i;
decltype(*p) c;//错误,c是int&,必须初始化
  • decltype不加括号,得到变量类型;若加括号,被编译器看作表达式。
decltype(i)e ;//正确,e是未初始化的int
decltype( (i) ) d ;//错误,d是int&,必须初始化
/*note:
decltype(var)当var是引用时,声明变量时引用;
decltype( (var) )得到的结果永远是引用。
*/

2.6自定义数据结构

2.6.1定义Sale_data类型

类内初始值可以放在花括号里或者等号右边,但是不可以使用圆括号。

2.6.2 使用Sale_data类

2.6.3 编写自己的头文件

  • 类所在头文件名字应该和类相同。
  • 头文件中应该包含只定义一次的实体,如类,const和constexpr变量。
  • 预处理器保证头文件被包含多次还可以安全工作,使用了#define,#ifdef,#endif指令。预处理器无视作用域规则,所有头文件都应该加上。
#ifndef xx_H
#define xx_H
#include <需要使用的头文件>
xxx//头文件内的内容
#endif

你可能感兴趣的:(c++)