2.1 C++程序结构
控制台程序结构:
创建控制台项目:
- 创建Win32 Console Application 的空项目
- 设置Character Set属性 为Not set 。
- 添加源文件(.cpp 格式)。
程序分析:
包含头文件的2种方式:
< >:编译器只搜索它预计查找标准头文件的目录。
" ":编译器先在包含此指令所在的源文件的目录中搜索头文件。如果头文件未找到,编译器再搜索存储标准头文件的目录。
- 在C++中,输入的来源或输出的目的地称为流。
- << 运算符 指出 数据流动的方向,从这个运算符右边的变量或字符串到左边的输出目的地。
自动生成的控制台项目
2.2 定义变量
2.2.1 命名变量
赋予变量的名称叫做标识符,或变量名。变量名可以包含字母A~z(大写或小写)、数字0 ~ 9 和下划线字符。变量名必须以字母或下划线开头。
在C++中经常采用这样一个约定,把以大写字母开头的名称用于类的名称,把以小写字母开头的名称用于变量。
2.2.1 声明变量
为了存储数据,不仅需要定义变量的名称,还需要将一段计算机内存与变量名关联起来,这个过程称为变量定义。
int value;
既是一个声明,又是一个定义。使用已声明的变量名value访问定义的一段计算机内存,可以在这段内存中存储一个int类型的值。
2.2.3 变量初始值
- int value = 0;
- 在C++中的另一种方法,函数表示法。 即 int value (0);
2.3 基本数据类型
2.3.6 字面值
在C++中,所有种类的常数都称为字面值。字面值是特定类型的值。
2.3.7 定义数据类型的同义词
- typedef 关键字 :定义现有类型的同义词。
2.3.8 具有特定值集的变量
-
枚举
enum Week{Mon,Tues,Wed,Thurs,Fri,Sat,Sun} thisweek
声明了名称为Week的枚举类型和变量thisweek,这个变量是枚举类型Week的一个实例。
定义了枚举类型后,可以用下面的形式定义另一个变量:
enum Week nextWeek;或 Week nextWeek;enum{Mon,Tues,Wed,Thurs,Fri,Sat,Sun} thisWeek,nextWeek,lastWeek;
此处没有指定枚举类型,所以不能引用它。
注意,因为不允许重复着个定义,所以根本不能定义这种枚举类型的其他变量。这样做就意味着不允许重新定义Mon 到Sun的值。
2.4 基本的输入/输出操作
C++ 输入/输出 围绕着数据流这个概念,在数据流中,可以把数据插入输出流或从输入流析取数据。
- cout : 标准输出流
- cin : 标准输入流。
这2个流的名称都定义在std名称空间中。
2.4.1 从键盘输入
通过标准输入流cin 从键盘获得输入:
析取运算符>> : 指向数据流动的方向。
-
std::cin >> num1 >> num2;
数据从cin依次流动到这2个变量。跳过所有前置的空白,所输入的第1个整数值被读入到num1;忽略num1后面的所有空白,所输入的第2个整数值被读入num2.按下Enter键时,流输入操作结束,然后继续执行下一个语句。
2.4.2 到命令行的输出
- std::cout << num1 << num2 ;
2.4.3 格式化输出
-
setw(n) 操作符,输出的值在n个空格宽的字段中遵循右对齐。 操作符在标准库头文件iomanip中定义。
注意,setw()操作符只对紧跟在它的插入运算符之后的单个输出值起作用。 -
std::setiosflags 操作符,使输出在给定字段宽度内左对齐。
cout<< std::setioflags(std::ios::left);
2.4.4 转义序列
- 转义序列:通过避开一些字符的默认解释,允许在字符串中包括利用其他方法不能表示的字符。转义序列一反斜杠(\)开头,反斜杠字符告诉编译器按照一种特殊的方法解释后面的字符。
2.5 C++中的计算
逗号运算符
2.5.6 计算顺序
运算符优先顺序:
2.6 类型转换和类型强制转换
-
在涉及不同类型变量或常量的表达式中,对于每个要执行的运算,编译器都必须把其中一个操作数的类型转换成与另一个操作数相匹配的类型。这个转换过程称为隐式类型转换。
-
编译器根据下表所示的由高到低的类型排序来确定将哪个操作数转换成另一个操作数的类型。
任何char、signed char、unsigned char、short 或 unsigned short 类型的操作数在操作之前至少被转换成int 类型。
2.6.2 显示类型转换
-
强制转换语句:static_cast< the_type_convert_to > (expression)
关键字static_cast 表明将静态地检查类型强制转换,即在编译程序时进行检查。在执行程序时,不再进行其他查看这种转换的应用是否安全的检查。
-
static_cast 运算的作用:将由表达式求得的值转换成在尖括号内指定的类型。static_cast<>(),圆括号内的表达式没有限制,从单个变量到包含许多嵌套圆括号的复杂表达式都可以。
static_cast<>()例:
2.7 AUTO关键字
- 在变量定义语句中可以将auto关键字用作变量的类型,变量的类型根据提供的初始值来判断。
2.8 查看类型
- typeid 操作符能够查看表达式的类型。要获得表达式的类型,需要编写 typeid(表达式),这会产生一个类型为 type_info的对象,该对象封装了表达式的类型。
typeid 操作符结果是一个对象,所以不能直接将它写到标准输出流。 可以用如下方式:
2.9 按位运算符
^ 异或运算符:相同为0,不同为1.
- 为什么左右移运算符与 输入、输出流中所用的运算符一样?
因为cin 和 cout 是流对象,因为它们是对象,所以可以由一个名为运算符重载的过程来重新定义运算符在不同上下文中的意义。这样,>>运算符就被重定义用于输入流对象(如cin)。<< 运算符同理。
2.10 lvalue 和 rvalue
C++中每个表达式的结果或者是 lvalue 或者是 rvalue。
- lvalue:指的是内存中持续存储数据的一个地址; 只包含一个命名变量的表达式始终是lvalue。
- rvalue:指的是临时存储的表达式结果;
2.11 了解存储时间和作用域
在程序执行时,所有的变量都有一个有限的生存期。从声明它们之时开始存在,然后在某个时刻消失。特定变量的生存时间由一个称作其存储时间的属性确定。
变量有3种不同的存储时间:
- 自动存储时间
- 静态存储时间
- 动态存储时间
变量具有哪种存储时间取决于它的创建方式。
变量的作用域:
变量的作用域仅仅是这个变量名在其中有效的那部分程序。
2.11.1 自动变量
- 声明的所有变量都具有自动存储时间,因而称为自动变量。
所声明的变量都是在一个代码块内声明的(是在一对{}的范围内声明的),这些变量称为自动变量。
一个自动变量在作用域中的时间从声明它那一刻开始,一直到包含取声明的代码块结束为止。 - 自动变量占用的空间在一个称为栈的内存区域中自动分配,栈是专门为此而留出的内存。栈默认容量是1MB。
2.11.3 全局变量
- 全局变量:在所有代码块和类之外声明的变量。具有全局作用域。在默认情况下具有静态存储时间。
- 具有静态存储时间的全局变量将从程序开始执行时存在,直到程序执行结束时为止。
- 每个全局变量的作用域都从定义它们的地方延伸到文件结尾处。
- 使用作用域解析云现付(::)获得全局变量:
“Value of global count1=” << count1
如果作用域解析运算符的左操作数指定了一个名称,那么编译器将在具有此名称的空间中,搜索指定为右操作数的名称。
2.11.4 静态变量
static int count
即使一个静态变量是在一个代码块内声明的,并且只能从这个代码块内部使用它,但是在程序的生存期内,它将持续存在。具有静态存储时间。静态变量默认初始值始终为0.
2.12.1 声明名称空间
myStuff 名称空间定义了一个作用域,在这个名称空间作用域的所有内容都由该名称空间名限定。
2.13 C++/CLI 编程
2.13.1 C++/CLI 特有的基本数据类型
在C++/CLI语言中,每个ISO/IEC 基本类型名称都将映射到在System名称空间中定义的值类类型。因此,在C++/CLI程序中,ISO/IEC基本类型名称是关联的值类类型的简略形式。
基本类型 | 大小 (字节) | CLI值类 |
---|---|---|
bool | 1 | System::Boolean |
char | 1 | System::SByte |
signed char | 1 | System::SByte |
unsigned char | 1 | System::Byte |
short | 2 | System::Int16 |
unsigned short | 2 | System::UInt16 |
int | 4 | System::Int32 |
unsigned int | 4 | System::UInt32 |
long | 4 | System::Int32 |
unsigned long | 4 | System::UInt32 |
long long | 8 | System::Int64 |
unsigned long long | 8 | System::UInt64 |
float | 4 | System::Single |
double | 8 | System::Double |
long double | 8 | System::Double |
wchar_t | 2 | System::Char |
System是根名称空间名,C++/CLI值类类型在这个名称空间中定义。
- 在C++/CLI中,与每个基本类型名称相关联的值类类型为这样的变量添加了重要的附加功能,在必要时,编译器将安排从原值到关联的值类类型对象的自动转换,或者进行相反的转换,这些过程分别称为装箱(boxing)和拆箱(unboxing)。
2.13.3 C++/CLI 特有的功能——格式化输出
一般,可以编写格式为{n,w:Axx}的格式规范:
{n,w:Axx}
- n:索引值,用于选择格式串之后的参数;
- w:可选的字段宽度规范;是一个 有符号整数。
如果w为正,则值在这个字段中将右对齐;
如果w为负,则左对齐。
如果值占用的位置数小于w指定的位置数,则输出将由空格填充;
如果值需要的位置数大于w指定的未知数,该宽度规范将被忽略。 - A:是单个字母,指定如何对值进行格式化;
- xx:是可选的1个或2个数字,指定值的精度。
一些非常有用的格式规范表
2.13.4 C++/CLI的键盘输入
- Console::ReadLine()函数:把整行输入作为字符串读取。
- Console::Read()函数:读取单个字符。
- Console::ReadKey()函数:读取所按的键。
2.13.5 使用safe_cast
safe_cast 运算在CLR环境中用于显式类型强制转换。
2.13.6 C++/CLI枚举
在C++/CLI 中定义一个枚举:
定义枚举时可以用 enum struct 代替 enum class ,两者等效。因为C++/CLI枚举是一种 类 类型,不能在局部定义它,需要在全局作用域中定义。
C++/CLI 程序中的枚举与ISO/IEC程序中的枚举的区别:
-
在访问C++/CLI枚举中的常量时,必须始终利用枚举类型名称限定正在使用的常量。例:Suit suit = Suit::Clubs;
-
enum class 是C++/CLI中的1个关键字,它将枚举标识为C++/CLI 。
-
在枚举中定义的常量 是对象,而在ISO/IEC C++枚举中仅仅是基本类型的值。
1.指定枚举常量的类型
C++/CLI枚举中的常量可以是下列任一种类型:
指定一个枚举中常量的类型,在枚举类型名之后写入类型,要用:隔开:
2. 指定枚举常量的值
3.枚举常量运算
如果枚举常量是除bool类型外的整数类型,可以用++或–来递增或递减枚举类型的变量。
也可以对枚举值应用 + 或 - 运算符:
也可以使用按位运算符(^、|、&和~)及关系运算符(==、 != 、<、<=、>、>= ).
4.使用枚举器作为标志
可以定义一个枚举(如枚举常量)来表示某物的标志或状态位。
2.14 查看C++/CLI 类型
对于变量x和y,表达式**(x*y).GetType()** 将产生类型为System::Type的一个对象,System::Type封装表达式的类型。当输出时,它会被自动转换成一个System::String 对象。
x::typeid 可以获得封装了x的类型的System::Type对象;
String::typeid 来获得System::String的System::Type对象;
2.17 本章主要内容
To be continue…