变量和基本类型

来源:互联网 发布:sip udp端口号5060 编辑:程序博客网 时间:2024/05/17 07:56

静态类型语言

C++ 是静态类型(statically typed)语言,在编译时执行类型检查。结果是程序中使用某个名字之前,必须先告知编译器该名字的类型。

什么是变量

变量提供了程序可以操作的有名字的存储区。C++ 中的每一个变量都有特定的类型,该类型决定了变量的内存大小和布局、能够存储于该内存中的值的取值范围以及可应用在该变量上的操作集。

初始化

变量定义指定了变量的类型和标识符,也可以为对象提供初始值。定义时指定了初始值的对象被称为是已初始化的。C++ 支持两种初始化变量的形式:复制初始化和直接初始化。复制初始化语法用等号(=),直接初始化则是把初始化式放在括号中:

int ival(1024); // direct-initializationint ival = 1024; // copy-initialization

在 C++ 中理解“初始化不是赋值”是必要的。初始化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替。

声明和定义

变量的定义用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。
声明用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern 关键字声明变量名而不定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern:
extern int i; // declares but does not define i
int i; // declares and defines i
extern 声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。
只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进行初始化。如果声明有初始化式,那么它可被当作是定义,即使声明标记为 extern:
extern double pi = 3.1416; // definition
虽然使用了 extern ,但是这条语句还是定义了 pi,分配并初始化了存储空间。只有当 extern 声明位于函数外部时,才可以含有初始化式。
变量从声明开始才可见。

const 对象默认为文件的局部变量

在全局作用域(第 2.3.6 节)里定义非 const 变量时,它在整个程序中都可以访问。我们可以把一个非 const 变更定义在一个文件中,假设已经做了合适的声明,就可在另外的文件中使用这个变量:

// file_1.ccint counter; // definition// file_2.ccextern int counter; // uses counter from file_1++counter; // increments counter defined in file_1

与其他变量不同,除非特别说明,在全局作用域声明的 const 变量是定义该对象的文件的局部变量。此变量只存在于那个文件中,不能被其他文件访问。
通过指定 const 变更为 extern,就可以在整个程序中访问 const 对象:

// file_1.cc// defines and initializes a const that is accessible to other filesextern const int bufSize = fcn();// file_2.ccextern const int bufSize; // uses bufSize from file_1// uses bufSize defined in file_1for (int index = 0; index != bufSize; ++index)// ...

本程序中,file_1.cc 通过函数 fcn 的返回值来定义和初始化 bufSize。而 bufSize 定义为 extern,也就意味着 bufSize 可以在其他的文件中使用。file_2.cc 中 extern 的声明同样是 extern;这种情况下,extern 标志着bufSize 是一个声明,所以没有初始化式。
我们将会在第 2.9.1 节看到为何 const 对象局部于文件创建。非 const 变量默认为 extern。要使 const 变量能够在其他的文件中访问,必须地指定它为 extern。

引用

引用就是对象的另一个名字。
引用是一种复合类型,通过在变量名前添加“&”符号来定义。复合类型是指用其他类型定义的类型。在引用的情况下,每一种引用类型都“关联到”某一其他类型。

const 引用

const 引用是指向 const 对象的引用。
“非 const 引用”表示指向非 const 类型的引用。

const int ival = 1024;const int &refVal = ival; // ok: both reference and object are const

const 引用可以初始化为不同类型的对象或者初始化为右值(第 2.3.1
节),如字面值常量:

int i = 42;// legal for const references onlyconst int &r = 42;const int &r2 = r + i;

同样的初始化对于非 const 引用却是不合法的,而且会导致编译时错误。非 const 引用只能绑定到与该引用同类型的对象。

float、 double 和 long double

类型 float、 double 和 long double 分别表示单精度浮点数、双精度浮点数和扩展精度浮点数。一般 float 类型用一个字(32 位)来表示,double 类型用两个字(64 位)来表示,long double 类型用三个或四个字(96 或 128 位)来表示。类型的取值范围决定了浮点数所含的有效数字位数。
对于实际的程序来说,float 类型精度通常是不够的——float 型只能保证 6 位有效数字,而 double 型至少可以保证 10 位有效数字,能满足大多数计算的需要。
决定使用哪种浮点型就容易多了:使用 double 类型基本上不会有错。在 float 类型中隐式的精度损失是不能忽视的,而 double 类型精度代价相对于 float 类型精度代价可以忽略。事实上,有些机器上,double类型比 float 类型的计算要快得多。long double 类型提供的精度通常没有必要,而且还需要承担额外的运行代价。

字符串字面值的连接

两个相邻的仅由空格、制表符或换行符分开的字符串字面值(或宽字符串字
面值),可连接成一个新字符串字面值。这使得多行书写长字符串字面值变得简
单:

// concatenated long string literalstd::cout << "a multi-line "             "string literal "             "using concatenation"          << std::endl;

执行这条语句将会输出:
a multi-line string literal using concatenation
如果连接字符串字面值和宽字符串字面值,将会出现什么结果呢?例如:

// Concatenating plain and wide character strings is undefinedstd::cout << "multi-line " L"literal " << std::endl;

其结果是未定义的,也就是说,连接不同类型的行为标准没有定义。这个程序可能会执行,也可能会崩溃或者产生没有用的值,而且在不同的编译器下程序的动作可能不同。

多行字面值

处理长字符串有一个更基本的(但不常使用)方法,这个方法依赖于很少使用的程序格式化特性:在一行的末尾加一反斜线符号可将此行和下一行当作同一行处理。

0 0
原创粉丝点击