Skip to content

Latest commit

 

History

History
183 lines (115 loc) · 7.92 KB

03-变量和基本类型.md

File metadata and controls

183 lines (115 loc) · 7.92 KB

变量与数据类型


1 基本内置类型

理解变量:变量是程序可操作的存储区的名称。C++中每个变量都有指定的类型,类型决定了变量存储的大小和布局。

C++定义了一套包括算术(arithmetic)类型和空类型(void)在内的基本数据类型。

  • 算术类型包括:整数、布尔类型、字符、和浮点类型。
  • 空类型不对应任何具体的值,仅用于一些特殊场合。

注意:不要混用有符号类型的数据和无符号类型的数据

    int va = -1;
    unsigned int vb = 1;
    int vc = va * vb;//此时va会自动转为为无符号类型的整数

整形

表示 整数 、 字符 和 布尔值 的算术类型合称为整型。

  • 字符类型:有 charwchar_t 两种。char 类型保证了有足够的空间,能够存储机器基本字符集中任何字符相应的数值,因此,char 类型通常是单个机器字节wchar_t 类型用于扩展字符集,比如汉字和日语,这些字符集中的一些字符不能用单个 char 表示。
  • 布尔值bool 类型表示真值 true 和 false。可以将算术类型的任何值赋给 bool 对象。0 值算术类型代表 false, 任何非 0 的值 都代表 true。

溢出

  • unsigned 类型:unsigned类型的数总是正值或0,负数总是超出其取值范围。并遵守 算数模 2的n次方定律 ,其中n是该类型占用的位数。例如,如果试图将 336 存储到 8 位的unsigned char 中,则实际赋值为80,因为 80 是 336 对 256 求模后的值。
  • signed 类型:由编译器决定实际赋的值。在实际操作中,很多的编译器处理 signed 类型的方式和 unsigned 类型类似。也就是说,赋值时是取该值对该类型取值数目求模后的值。然而我们不能保证编译器都会这样处理 signed 类型。

浮点型

类型 float、 double 和 long double 分别表示单精度浮点数、双精度浮点数和扩展精度浮点数。

  • float 类型用一个字(32 位)来表示,
  • double 类型用两个字(64 位)来表示,
  • long double 类型用三个或四个字(96 或 128 位)来表示。

类型的取值范围决定了浮点数所含的有效数字位数。 float 型只能保证 6 位有效数字 ,而 double 型至少可以保证 10 位有效数字


2 复合类型

复合类型是指基于其他基本类型定义的类型。比如引用和指针

2.1 引用

一般使用的术语引用指的是左值引用。引用为对象起了另外一个名字,引用类型引用另外一种类型。通过将声明符写成&d(每个引用都必须以&开头)来定义引用类型,其中d是声明的变量名。 定义引用类型时,引用类型必需被初始化。引用并非对象,它只是为一个已经存在的对象取另一个名字。

引用类型一经被初始化,就一直和它的初始值对象绑定在一起。

2.2 指针

指针是指向另一种类型的复合类型,与引用不同的是:

  • 指针本身是一个对象,允许对指针进行赋值和拷贝。
  • 指针无需在定义时初始化,引用必须在创建时被初始化。
  • 不存在空引用。引用必须连接到一块合法的内存。但存在空指针。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。

指针值有以下四种状态:

  • 指向一个对象
  • 指向临近对象所占空间的下一个位置
  • 空指针,没有指向任何对象
  • 无效指针

NULL是一个预处理变量,用来给指针赋值,定义在cstdlib中,它的值是0

void*指针是一种特殊的指针类型,可用于存放任意对象的地址。

2.3 const限定符

const用于定义常量,默认状态下,const仅在文件内有效。如果想在多个文件内共享const变量,必需在const变量的定义之前添加extern关键字。在其文件中使用extern声明

//file1.cpp
extern const int size = 100;

//file2.cpp
extern const int size//与file1的size是同一个

const的引用

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

const  int c1 = 1024;
cosnt int &r1 = c1;

const与指针

  • 指向常量的指针:const int *p = &i,不能通过p给i赋值
  • const指针:int *const p = &1,不能修改p指向别的int类型

const int *p = &i中离p最近的是*,表示它是一个指针,剩余部分const int说明它指向的是int常量 int *const p = &1中离p最近的是const,所以p是一个常量,然后剩余部分觉得它的类型,int *表示它是一个int指针

2.4 constexpr常量表达式

常量表达式是指值不会改变且在编译阶段就能计算结果的表达式。

const int a = 32;//a是一个常量表达式
const int b = a+1;//b是一个常量表达式
int c = 32;//c不是一个常量表达式,它没有被const修饰
const int szie = get_size();//size不是一个常量表达式,其值在运行时才能确认。

C++11新标准规定,允许将变量声明为constexpr类型,以便编译器来校验变量的值是否为一个常量表达式。声明constexpr的变量一定是常量,且必需使用常量表达式。

指针和constexpr

在constexpr声明中如果使用了指针,限定符constexpr仅对指针有效,与指针所指的对象无关。

    const int *pA = nullPtr;//pA是一个指向普通整型常量的指针,即无法修改指针的指向
    constexpr int *pB = nullPtr;//pB是一个指向普通整型的常量指针,即无法修改指针的指向

2.5 处理类型

类型别名

使用typedef可以给数据类型起新的名字。

auto类型说明符

C++11新标准引入了auto类型说明符,用它可以让编译器替开发者分析表达式所属的类型。

decltype类型指示符

如果系统从表达式推断出要定义的类型,但是又不希望使用该表达式的结果作为初始化值,则可以使用C++11引入的第二种类型说明符decltype

decltype(f()) value = x;//value的类型就是f的返回值类型。

C++ 中的变量声明

变量声明向编译器保证变量以给定的类型和名称存在,这样编译器在不需要知道变量完整细节的情况下也能继续进一步的编译。变量声明只在编译时有它的意义,在程序连接时编译器需要实际的变量声明。

2.6 自定义数据结构

C/C++ 数组允许定义可存储相同类型数据项的变量,但是结构是 C++ 中另一种用户自定义的可用的数据类型,它允许你存储不同类型的数据项。

从最基本的层面理解,数据结构就是把一组相关的数据元素组织起来然后使用它们的成员和方法。 C++允许用户以类的形式自定义数据类型。

  • 可以使用struct关键字定义数据结构
  • C++11新的规定,可以为类内数据成员定义初始化值
  • 类(数据机构)的定义应该放在头文件中。每个头文件都应该使用预编译指定防止重复引用。

类与结构体在C++中只有两点区别,除此这外无任何区别:

  • class中默认的成员访问权限是private的,而struct中则是public的。  
  • 从class继承默认是private继承,而从struct继承默认是public继承。

3 初始化规则

默认初始化规则

定义基本数据类型变量(单个值、数组)的同时可以指定初始值,如果未指定C++会去执行默认初始化(default-initialization)。 那么什么是”默认初始化”呢?

  • 栈中的变量(函数体中的自动变量)和堆中的变量(动态内存)会保有不确定的值;
  • 全局变量和静态变量(包括局部静态变量)会初始化为零。

函数体中的变量定义是这样的规则:

int i;                    // 不确定值
int i = int();            // 0
int *p = new int;         // 不确定值
int *p = new int();       // 0