您的位置:首页 > 编程语言 > C语言/C++

[C++Primer] 第二章 变量和基本类型

2016-05-16 22:32 519 查看

2.1 基本内置类型

C++定义了一套包括算术类型 (arithmeric type) 和空类型 (void) 在内的基本数据类型。其中算术类型包含了字符、

整型数、 布尔值和浮点数。空类型不对应具体的值,仅用于一些特殊的场合,例如最常见的是,当函数不返回任何值时使用空类型作为返回类型

2.1.1 算数类型

算术类型分为两类:整型 (integral type,包括字符和布尔类型在内)和浮点型



类型 int、short、long 和 long long 都是带符号的,通过在这些类型名前添加 unsigned 就可以得到无符号类型,例如 unsigned long。类型 unsigned int 可以缩写为 unsigned

类型 char 和类型 signed char 并不一样

2.1.2 类型转换

#include <iostream>
int main(){
unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl;
std::cout << u - u2 << std::endl;
int i=10, i2= 42;
std::cout << i2 -i<< std::endl;
std::cout << i - i2<< std::endl;
std::cout << i - u<< std::endl;
std::cout << u - i<< std::endl;
return 0;
}


2.1.3 字面值常量

一个形如42的值被称作字面值常量(literal)

整型和浮点型字面值

20 /* 十进制 */ 024 /* 八进制 */ 0x14 /* 十六进制 */


浮点数

3.14159 3.14159E0 0. 0e0 .001


字符和字符串字面值

// 分多行书写的字符串字面值
std::cout << "a rea11y, rea11y long string litera1 "
"that spans two 1ines" << std::end1;


转义序列

换行符     \n  横向制表符   \t  报警(响铃)符 \a
纵向制表符   \v  退格符     \b  双引号         \"
反斜线     \\  问号          \?  单引号         \'
回车符     \r  进纸符     \f


2.2 变量

变量提供一个具名的、可供程序操作的存储空间。C++中的每个变量都有其数据类型,数据类型决定着变量所占内存空间的大小和布局方式、该空间能存储的值的范围,以及变量能参与的运算。对C++程序员来说,”变量 (variable)” 和 “对象 (object)” 一般可以互换使用。

2.2.1 变量定义

变量定义的基本形式是:首先是类型说明符(type specifier),随后紧跟由一个或多个变量名组成的列表,其中变量名以逗号分隔,最后以分号结束。

初始值

2.2.2 变量声明和定义的关系

分离式编译 (separate compilation) 机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译。

声明extern和定义

2.2.3 标识符

变量命名规范

变量命名有许多约定俗成的规范, 下面的这些规范能有效提高程序的可读性:

标识符要能体现实际含义。

变量名一般用小写字母, 如index, 不要使用Index或INDEX。

用户自定义的类名一般以大写字母开头, 如 Sales_item。

如果标识符由多个单词组成, 则单同间应有明显区分, 如 student_loan 或studentLoan, 不要使用 studentloano

2.2.4 名字的作用域

嵌套的作用域

#include <iostream>
int reused = 42;
int main(){
int unique = 0;
std::cout << reused <<" "<< unique << std::endl;
int reused = 0;
std::cout<<reused<<" "<<unique <<std::endl;
std::cout << ::reused <<" "<<unique <<std::endl;
return 0;
}


#include <iostream>
int main(){
int i = 100, sum = 0;
for(int i = 0;i != 10; ++i)
sum += i;
std::cout << i << " " << sum << std::endl;
return 0;
}


2.3 复合类型

2.3.1 引用

引用 (reference) 为对象起了另外一个名字,引用类型引用 (refers to)另外一种类型。通过将声明符写成 &d 的形式来定义引用类型,其中 d 是声明的变量名:

int ival = 1024;
int &refVa1 = iva1; // refVa1指向iva1(是iva1的另一个名字)
int &refVa12; // 报错:引用必须被初始化


一般在初始化变量时,初始值会被拷贝到新建的对象中。然而定义引用时,程序把引用和它的初始值绑定 (bind) 在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。

#include <iostream>
int main(){
int i = 1, &r1 = i;
double d = 0.0, &r2 = d;
std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl;
// T
r2 = 3.14159;
std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl;
// T
r2 = r1;
std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl;
// F
i = r2;
std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl;
// F
r1 = d;
std::cout << i << " " << r1 << " " << d << " " << r2 << " " << &r1 << " " << &r2 << std::endl;
return 0;
}


#include <iostream>
int main(){
int i = 1, &r1 = i;
i = 5;
r1 = 10;
std::cout << i << " " << r1 << std::endl;
return 0;
}


2.3.2 指针

指针 (pointer) 是 “指向(point to)” 另外一种类型的复合类型。 与引用类似,指针也实现了对其他对象的间接访问。然而指针与引用相比又有很多不同点。

其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。

其二,指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

指针存放某个对象的地址,要获取该地址,需要使用取地址符 (操作符 &)

int ival = 42;
int *p = &iva1; // p存放变量iva1的地址, 或者说p是指向交量ival的指针
double dval;
// 正确 : 初始位是 double 型对象的地址
double *pd = &dval;
// 正确 : 初始位是指向 double 对象的指针
double *pd2 = pd;
int *pi = pd;
// 错误: 指针pJ.的类型和pd的类型不匹配
pi = &dval;
// 错误: 试图把double型对象的地址赋给int型指针


如果指针指向了一个对象,则允许使用解引用符 (操作符 * 来访问该对象:

int ival = 42;
int *p = &ival; // p存放着变量ival的地址。或者说p是指向交量ival的指针
cout << *p; // 由符号*得到指针p指的对象,输出42


对指针解引用会得出所指的对象,因此如果给解引用的结果赋值,实际上也就是给指针所指的对象赋值:

*p = 0; // 由符号*得到指针p所指的对象, 即可经由p为交量ival赋值
cout<<*p; // 出0


int &r = i;
int *p;
p = &i;
*p = i;
int &r2 = *p
// &是声明的一部分, *是一个解引用符


int i = 42;
int &r = i; // r 是引用
int *p; // p 是指针
p = &i; // & 取地址符
*p = i; // * 解引用符
int &r2 = *p; // * 解引用符


空指针

int *p1 = nullptr; // 等价于 int *p1 = 0;
int *p2 = 0; // 直接将p2初始化为字面常数0
// 需要首先#include cstdlib
int *p3 = NULL; // 等价于int*p3 = 0;


2.4 const 限定符

2.5 处理类型

类型别名 (type alias) 是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它让复杂的类型名字变得简单明了、 易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。

typedef double wages; //wages 是 double 的同义词
using SI = Sales_item; // SI是Sales_item的同义词


2.6 自定义数据结构

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++