TsinghuaX: 00740043X C++语言程序设计基础 第二章提纲

第2章主要内容和教学要求

计算机的最基本功能是数据处理

  • C++支持的基本数据类型:
    • 整数、实数、字符、布尔数据
  • C++支持的基本运算
    • 算术运算、关系运算、逻辑运算、位运算、逗号运算、条件运算

程序要能够输入数据、输出数据

  • C++中的数据输入/输出可以调用预定义的功能模块实现

程序的执行流程

  • 顺序的,因此程序要能够
  • 对执行流程进行选择(选择、开关语句);
  • 反复用同一算法依次处理大批量数据(循环语句)。

枚举类型

  • 通过列出所有可取值来定义一种新类型。

学习要求:

  • 学习视频课件;
  • 阅读教材第2章;
  • 按照实验指导视频或者《C++语言程序设计(第4版)学生用书》完成实验;
  • 完成在线选择题和编程题;

参考教材

  • 《C++语言程序设计》(第4版),郑莉等编著,清华大学出版社出版
  • 《C++语言程序设计(第4版)学生用书》,郑莉等编著,清华大学出版社出版

 

C++的特点和程序实例

C++的产生和发展

  • 从C语言发展演变而来,最初被称为"带类的C";
  • 1983年正式取名为C++;
  • 1998年11月被国际标准化组织(ISO)批准为国际标准;
  • 2003年10月15日发布第2版C++标准ISO/IEC 14882:2003;
  • 2011年8月12日ISO公布了第三版C++标准C++11,包含核心语言的新机能、扩展C++标准程序库。
  • 2014年8月18日ISO公布了C++14,其正式名称为"International Standard ISO/IEC 14882:2014(E) Programming Language C++"。
  • C++14作为C++11的一个小扩展,主要提供漏洞修复和小的改进。

C++的特点

  • 兼容C,支持面向过程的程序设计;
  • 支持面向对象的方法;
  • 支持泛型程序设计方法。

命名空间

避免命名冲突

std是C++标准库的命名空间( namespace)名

using namespace std表示打开std命名空间

例2-1

#include <iostream>

using namespace std;

int main() {

cout << "Hello!" << endl;

cout << "Welcome to c++!" << endl;

return 0;

}

运行结果:

Hello!

Welcome to c++!

 

C++字符集和词法记号

 

字符集

  • 大小写的英文字母:A~Z,a~z
  • 数字字符:0~9
  • 特殊字符:

! # % ^ & * _ + = - ~ < > / \ ; . , : ? ( ) [ ] { }   |

词法记号

  • 关键字 C++预定义的单词
  • 标识符 程序员声明的单词,它命名程序正文中的一些实体
  • 文字 在程序中直接使用符号表示的数据
  • 分隔符 ()   {}   ,    :    ; 
    用于分隔各个词法记号或程序正文
  • 运算符(操作符) 用于实现各种运算的符号
  • 空白符 空格、制表符(TAB键产生的字符)、垂直制表符、换行符、回车符和注释的总称

标识符的构成规则

  • 以大写字母、小写字母或下划线(_)开始。
  • 可以由以大写字母、小写字母、下划线(_)或数字0~9组成。
  • 大写字母和小写字母代表不同的标识符。
  • 不能是C++关键字或操作符。

 

基本数据类型、常量、变量

 

C++能够处理的基本数据类型

  • 整数类型;
  • 浮点数类型;
  • 字符类型;
  • 布尔类型。

 

程序中的数据

  • 常量
    • 在源程序中直接写明的数据;
    • 其值在整个程序运行期间不可改变。
  • 变量
    • 在程序运行过程中允许改变的数据。

 

整数类型

  • 基本的整数类型:int
  • 按符号分
    • 符号的(signed)
    • 无符号的(unsigned)
  • 按照数据范围分     
    • 短整数(short)
    • 长整数(long)
    • 长长整数( long long )
  • ISO C++标准并没有明确规定每种数据类型的字节数和取值范围,它只是规定它们之间的字节数大小顺序满足:

(signed/unsigned)signed char ≤ (unsigned) short int ≤ (unsigned) int ≤ (unsigned) long int ≤ long long int

 

字符类型l(char)

  • 容纳单个字符的编码;
  • 实质上存储的也是整数。

 

浮点数类型

  • 单精度(float)
  • 双精度(double)
  • 扩展精度(long  double)

 

字符串类型(详见第6章)

  • 有字符串常量
  • 基本类型中没有字符串变量
  • 采用字符数组存储字符串(C风格的字符串)
  • 标准C++类库中的String类(C++风格的字符串)

 

布尔类型(bool)

  • 只有两个值:true(真) 、false(假)
  • 常用来表示关系比较、相等比较或逻辑运算的结果

 

各基本类型的取值范围

 

 

常量

  • 在程序运行的整个过程中其值始终不可改变的量;
  • 直接使用符号(文字)表示的值;
  • 例如:12,3.5,'A'都是常量。

整数常量

  • 以文字形式出现的整数;
  • 十进制 
    • 若干个0~9的数字,但数字部分不能以0开头,正数前边的正号可以省略。
  • 八进制
    • 前导0+若干个0~7的数字。
  • 十六进制
    • 前导0x+若干个0~9的数字及A~F的字母(大小写均可)。
  • 后缀
    • 后缀L(或l)表示类型至少是long,后缀LL(或ll)表示类型是long long,后缀U(或u)表示unsigned类型。

浮点数常量

  • 以文字形式出现的实数;
  • 一般形式:
    • 例如,12.5,-12.5等。
  • 指数形式:
    • 例如,0.345E+2,-34.4E-3;
    • 整数部分和小数部分可以省略其一。
  • 浮点常量默认为double型,如果后缀F(或f)可以使其成为float型,例如:12.3f。

 

字符常量

  • 单引号括起来的一个字符,如:'a'、'D'、'?'、'$';
  • C++转义字符列表(用于在程序中表示不可显示字符)

 

 

 

C风格字符串常量

  • 一对双引号括起来的字符序列;
  • 在内存中按串中字符的排列次序顺序存放,每个字符占一个字节;
  • 在末尾添加 ‘\0’ 作为结尾标记。

例:

 

 

通过添加前缀可以改变字符常量或者字符串常量的类型,前缀及其含义如下表所示: 

 

 

变量:在程序的运行过程中,其值可变的量

  • 变量定义
    • 数据类型    变量名1, 变量名2, ..., 变量名n;
  • 初始化
    • C++语言中提供了多种初始化方式;
    • 例如:

int a = 0;

int a(0);

int a = {0};

int a{0};

其中使用大括号的初始化方式称为列表初始化,列表初始化时不允许信息的丢失。例如用double值初始化int变量,就会造成数据丢失。

 

符号常量

  • 常量定义语句的形式为:
    • const  数据类型说明符  常量名=常量值;

或:

    • 数据类型说明符  const  常量名=常量值;
  • 例如,可以定义一个代表圆周率的符号常量:
    • const float PI = 3.1415926;
  • 符号常量在定义时一定要初始化,在程序中间不能改变其值。

 

程序举例

 

题目:读入并显示整数

  • 主要知识点:
    • 常量
      • 在源程序中直接写明的数据,其值在整个程序运行期间不可改变,这样的数据称为常量。
    • 变量
      • 在运行过程中从计算机的外部设备(例如键盘、硬盘)读取的,这些数据的值在程序运行过程中允许改变,这样的数据称为变量
    • 从键盘输入数据
      • iostream类的对象cin的>>操作,可以从标准输入设备(通常是键盘)读入数据
    • 数据的存储
      • 为了存储数据,需要预先为这些数据分配内存空间。
      • 变量的定义就是在给变量命名的时候分配内存空间。
  • 源代码

#include <iostream>

using namespace std;

int main()

{

     int radius;

     cout<<"Please enter the radius!\n";

     cin>>radius;

     cout<<“The radius is:”<<radius<<‘\n’;    

   cout<<“PI is:”<<3.14<<‘\n’;

     cout<<"Please enter a different radius!\n"; 

     cin>>radius;

     cout<<"Now the radius is changed to:"  

             <<radius<<‘\n’;

     return 0;

}

 

题目:为常量命名

  • 主要知识点:符号常量
  • 源代码

#include <iostream>

using namespace std;

int main()

{   const double pi(3.14159);  

     int radius;

     cout<<"Please enter the radius!\n";

     cin>>radius;

     cout<<"The radius is:"<<radius<<'\n';

     cout<<"PI is:"<<pi<<'\n';

     cout<<"Please enter a different radius!\n"; 

     cin>>radius;

     cout<<"Now the radius is changed to:"<<radius<<'\n';

     cout<<"PI is still:"<<pi<<'\n‘;

     //cin>>pi;

     return 0;

}

  • 运行结果:

Please enter the radius!

2

The radius is:2

PI is:3.14159

Please enter a different radius!

3

Now the radius is changed to:3

PI is still:3.14159

 

题目:变量的初始化

  • 主要知识点:变量的初始化
    • 虽然变量的值是可以在运行时获得的,但是在定义变量时也可以进行初始化,而且应该提倡进行初始化;
    • 未经初始化的变量,其值可能是随机的。如果误用了未经初始化也没有给予确定值的变量,就会引起错误。
  • 源代码

#include <iostream>

using namespace std;

int main()

{

     const double pi(3.14159);  

     int radius(0);

     cout<<"The initial radius is:"<<radius<<'\n';

     cout<<"PI is:"<<pi<<'\n‘; 。

     cout<<"Please enter a different radius!\n"; 

     cin>>radius;

     cout<<"Now the radius is changed to:"<<radius<<'\n';

     cout<<“PI is still:”<<pi<<‘\n’;

     return 0;

}    

 

算术运算与赋值运算

 

算术运算

  • 基本算术运算符
    • +  -  *  /(若整数相除,结果取整)
    • %(取余,操作数为整数)
  • 优先级与结合性
    • 先乘除,后加减,同级自左至右
  • ++, --(自增、自减)
    • 例:i++;    --j;

赋值运算

  • 将值赋给变量
  • 赋值运算符“=”
  • 赋值表达式:
    • 用赋值运算符连接的表达式
    • 例:

n=5

n = n + 5

    • 表达式的值
      赋值运算符左边对象被赋值后的值
    • 表达式的类型
      赋值运算符左边对象的类型
  • 复合的赋值运算符
    • +=,-=,*=,/=,%=,<<=,>>=,&=,^=,|= 

    • a += 3 等价于 a = a + 3
      x *= y + 8 等价于 x = x * (y + 8)

 

逗号运算、关系运算、逻辑运算和条件运算

逗号运算和逗号表达式

  • 格式

表达式1,表达式2

  • 求解顺序及结果
    • 先求解表达式1,再求解表达式2
    • 最终结果为表达式2的值

a = 3 * 5 , a * 4   最终结果为60

 

关系运算与关系表达式

  • 关系运算是比较简单的一种逻辑运算,优先次序为:
     
  • 关系表达式是一种最简单的逻辑表达式
    • 其结果类型为 bool,值只能为 true 或 false。
  • 例如:a > b,c <= a + b,x + y == 3

 

逻辑运算与逻辑表达式

  • 逻辑运算符
               !(非)      &&(与)        ||(或)
    优先次序:   高         →            低
  • 逻辑运算结果类型:bool,值只能为 true 或 false
  • 逻辑表达式
    例如:(a > b) && (x > y)

 

“&&”(逻辑与)运算

  • “&&”的运算规则
    • 两侧表达式都为真,结果为真;
    • 有一侧表达式为假,结果为假。
  • “&&” 的“短路特性”

表达式1 && 表达式2

  • 先求解表达式1
  • 若表达式1的值为false,则最终结果为false,不再求解表达式2
  • 若表达式1的结果为true,则求解表达式2,以表达式2的结果作为最终结果

 

“||”(逻辑或)运算

  • “||”的运算规则
    • 两侧表达式都为假,结果为假;
    • 有一侧表达式为真,结果为真。
  • “||” 的“短路特性”

表达式1 || 表达式2

  • 先求解表达式1
  • 若表达式1的值为true,则最终结果为true,不再求解表达式2
  • 若表达式1的结果为false,则求解表达式2,以表达式2的结果作为最终结果

 

条件运算符与条件表达式

  • 一般形式
    • 表达式1?表达式2:表达式3

表达式1 必须是 bool 类型

  • 执行顺序
    • 先求解表达式1,
    • 若表达式1的值为true,则求解表达式2,表达式2的值为最终结果
    • 若表达式1的值为false,则求解表达式3,表达式3的值为最终结果

例:

   x = a > b ? a : b;

 

如果a>b为false,计算

如果a>b为true,计算

 

条件运算的优先级

  • 条件运算符优先级高于赋值运算符,低于逻辑运算符

 

  • 表达式1是bool类型,表达式2、3的类型可以不同,条件表达式的最终类型为 2 和 3 中较高的类型。

 

Sizeof运算、位运算

 

sizeof运算

  • 语法形式
    sizeof (类型名)
    或 sizeof 表达式
  • 结果值:
    “类型名”所指定的类型,或“表达式”的结果类型所占的字节数。
  • 例:

sizeof(short)

sizeof  x

位运算——按位与(&)

  • 运算规则

将两个运算量的每一个位进行逻辑与操作

  • 举例:计算 3 & 5

 

  • 用途:
    • 将某一位置0,其他位不变。
      例如:将char型变量a的最低位置0: a = a & 0xfe;
    • 取指定位。
      例如:有char c; int a; 取出a的低字节,置于c中:c=a & 0xff;

位运算——按位或(|)

  • 运算规则
    • 将两个运算量的每一个位进行逻辑或操作
  • 举例:计算 3 | 5

 

  • 用途:
    • 将某些位置1,其他位不变。
      例如:将 int 型变量 a 的低字节置 1 :
               a = a | 0xff;

位运算——按位异或(^)

  • 运算规则
    • 两个操作数进行异或:
      若对应位相同,则结果该位为 0,
      若对应位不同,则结果该位为 1,
  • 举例:计算 071^052

 

  • 用途举例:使特定位翻转(与0异或保持原值,与1异或取反)

例如:要使 01111010 低四位翻转:

 

位运算——取反(~)

  • 运算规则
    • 单目运算符,对一个二进制数按位取反。
  • 例:

 025:0000000000010101

 ~025:1111111111101010

位运算——移位(<<、>>)

  • 左移运算(<<)

左移后,低位补0,高位舍弃。

  • 右移运算(>>)

右移后:

低位:舍弃

高位:

无符号数:补0

有符号数:补“符号位”

 

运算优先级、类型转换

 

运算符优先级

 

 

混合运算时数据类型的转换

  • 一些二元运算符(算术运算符、关系运算符、逻辑运算符、位运算符和赋值运算符)要求两个操作数的类型一致。
  • 在算术运算和关系运算中如果参与运算的操作数类型不一致,编译系统会自动对数据进行转换(即隐含转换),基本原则是将低类型数据转换为高类型数据。

 

 

 

 

第2章(二)

数据的输入和输出

 

I/O流

  • 在C++中,将数据从一个对象到另一个对象的流动抽象为“流”。流在使用前要被建立,使用后要被删除。
  • 数据的输入与输出是通过I/O流来实现的,cin和cout是预定义的流类对象。cin用来处理标准输入,即键盘输入。cout用来处理标准输出,即屏幕输出。
  • 从流中获取数据的操作称为提取操作,向流中添加数据的操作称为插入操作。

 

预定义的插入符和提取符

  • “<<”是预定义的插入符,作用在流类对象cout上便可以实现项标准输出设备输出。
    • cout << 表达式 << 表达式...
  • 标准输入是将提取符作用在流类对象cin上。
    • cin >> 表达式 >> 表达式...
  • 提取符可以连续写多个,每个后面跟一个表达式,该表达式通常是用于存放输入值的变量。例如:
    • int a, b;
    • cin >> a >> b;

 

常用的I/O流类库操纵符

 

 

例:cout << setw(5) << setprecision(3) << 3.1415;

 

if语句

If语句的语法形式

if (表达式) 语句

例:if (x > y) cout << x;

if (表达式) 语句1 else 语句2

例:if (x > y) cout << x;

else cout << y;

if (表达式1) 语句1
else if (表达式2) 语句2
else if (表达式3) 语句3
           …
else 语句 n

 

例2-2输入一个年份,判断是否闰年

#include <iostream>

using namespace std;

int main() {

int year;

bool isLeapYear;

cout << "Enter the year: ";

cin >> year;

isLeapYear = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));

if (isLeapYear)

cout << year << " is a leap year" << endl;

else

cout << year << " is not a leap year" << endl;

return 0;

}

 

嵌套的if结构

  • 语法形式

 if(   )

 if(   ) 语句 1

else 语句 2

else

 if(   ) 语句 3

else 语句 4

  • 注意
    • 语句 1、2、3、4 可以是复合语句;
    • 每层的 if 与 else 配对,或用 { } 来确定层次关系。

 

例2-3:输入两个整数,比较两个数的大小

#include<iostream>

using namespace std;

int main() {

int x, y;

cout << "Enter x and y:";

cin >> x >> y;

if (x != y)

if (x > y)

cout << "x > y" << endl;

else

cout << "x < y" << endl;

else

cout << "x = y" << endl;

return 0;

}

 

switch语句

  • 语法形式

switch  (表达式)

     {  case    常量表达式 1:语句1

        case   常量表达式 2:语句2

                  ┆

        case   常量表达式 n:语句n

        default :             语句n+1

     }

  • 执行顺序
    • 以case中的常量表达式值为入口标号,由此开始顺序执行。因此,每个case分支最后应该加break语句。
  • 注意
    • case分支可包含多个语句,且不用{ }。
    • 表达式、判断值都是int型或char型。
    • 如果若干分支执行内容相同可共用一组语句。

 

例2-4:输入一个0~6的整数,转换成星期输出

#include <iostream>

using namespace std;

int main() {

     int day;

     cin >> day;

     switch (day) {

     case 0: cout << "Sunday" << endl; break;

     case 1: cout << "Monday" << endl; break;

     case 2: cout << "Tuesday" << endl; break;

     case 3: cout << "Wednesday" << endl; break;

     case 4: cout << "Thursday" << endl; break;

     case 5: cout << "Friday" << endl; break;

     case 6: cout << "Saturday" << endl; break;

     default:

        cout<<"Day out of range Sunday .. Saturday"<< endl;   break;

     }

     return 0;

}

while语句

  • 语法形式

while  (表达式)  语句

 

 

 

  • 执行顺序

先判断表达式的值,若为 true 时,执行语句。

 

例2-5 求自然数1~10之和

#include <iostream>

using namespace std;

int main() {

  int i = 1, sum = 0;

  while (i <= 10) {

      sum += i;  //相当于sum = sum + i;

      i++;

  }

  cout << "sum = " << sum << endl;

return 0;

}

do-while语句

  • do-while 语句的语法形式

do   语句

while (表达式)

  • 执行顺序

先执行循环体语句,后判断条件。
表达式为 true 时,继续执行循环体。

 

例2-6:输入一个数,将各位数字翻转后输出

#include <iostream>

using namespace std;

int main() {

int n, right_digit, newnum = 0; 

cout << "Enter the number: ";

cin >> n;

cout << "The number in reverse order is  ";

do {

right_digit = n % 10;

cout << right_digit;

n /= 10;  /*相当于n=n/10*/

} while (n != 0);

    cout << endl;

return 0;

}

 

例2-7用do-while语句编程,求自然数1~10之和

#include <iostream>

using namespace std;

int main() {

int i = 1, sum = 0;

do {

sum += i;

i++;

} while (i <= 10);

cout << "sum = " << sum << endl;

return 0;

}

 

 

 

 

 

 

 

 

 

对比下面的程序

 

程序1:

#include <iostream>

using namespace std;

int main() {

  int i, sum = 0;

  cin >> i;

  while (i <= 10) {

    sum += i;

    i++;

  }

  cout<< "sum= " << sum

       << endl;

  return 0;

}

程序2:

#include <iostream>

using namespace std;

int main() {

  int i, sum = 0;

  cin >> i;

  do {

    sum += i;

    i++;

  } while (i <= 10);

  cout << "sum=" << sum

       << endl;

  return 0;

}

 

 

for语句

  • for语句语法形式:

  

 

  • for语句的另一种形式:范围for语句:

    for  (声明:表达式)

        语句

 

例2-8:输入一个整数,求出它的所有因子

#include <iostream>

using namespace std;

int main() { 

int n;

cout << "Enter a positive integer: ";

cin >> n;

cout << "Number  " << n << "   Factors  ";

for (int k = 1; k <= n; k++)

  if (n % k == 0)

    cout << k << "  ";

  cout << endl;

  return 0;

}

 

运行结果1:

Enter a positive integer: 36

Number  36  Factors  1  2  3  4  6  9  12  18  36  

 

运行结果2:

Enter a positive integer: 7

Number  7   Factors  1  7  

 

嵌套的控制结构、其他控制语句

例2-10 输入一系列整数,统计出正整数个数i和负整数个数j,读入0则结束。

#include <iostream>

using namespace std;

 

int main() {

int i = 0, j = 0, n;

cout <<"Enter some integers please (enter 0 to quit):" << endl;

cin >> n;

while (n != 0) {

  if (n > 0) i += 1;

  if (n < 0) j += 1;

  cin >> n;

}

cout << "Count of positive integers: " << i << endl;

cout << "Count of negative integers: " << j << endl;

return 0;

}

其他控制语句

  • break语句

使程序从循环体和switch语句内跳出,继续执行逻辑上的下一条语句。不宜用在别处。

  • continue 语句

结束本次循环,接着判断是否执行下一次循环。

  • goto 语句

使程序的执行流程跳转到语句标号所指定的语句。不提倡使用。

 

自定义类型

类型别名:为已有类型另外命名

  • typedef  已有类型名  新类型名表
    • 例:

typedef double Area, Volume;

typedef int Natural;

Natural i1,i2;

Area a;

Volume v;

  • using  新类型名 = 已有类型名;
    • 例:

using Area = double;

using Volume = double;

枚举类型

  • 定义方式:

将全部可取值一一列举出来。

  • 语法形式:

enum  枚举类型名  {变量值列表};

例:enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};

默认情况下

SUN=0,MON=1,TUE=2,......,SAT=6

 

C++包含两种枚举类型:

  • 不限定作用域枚举类型:

enum  枚举类型名  {变量值列表};

  • 限定作用域的enum类将在第4章介绍。

 

不限定作用域枚举类型说明:

  • 枚举元素是常量,不能对它们赋值

例如有如下定义
enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};

不能写赋值表达式:SUN = 0

  • 枚举元素具有默认值,它们依次为: 0,1,2,......。
  • 也可以在声明时另行指定枚举元素的值,如:

enum Weekday{SUN=7,MON=1,TUE,WED, THU,FRI,SAT};

  • 也可以在声明时另行指定枚举元素的值;
  • 枚举值可以进行关系运算。
  • 整数值不能直接赋给枚举变量,如需要将整数赋值给枚举变量,应进行强
    制类型转换。
  • 枚举值可以赋给整型变量。

 

例2-11

  • 设某次体育比赛的结果有四种可能:胜(WIN)、负(LOSE)、平局(TIE)、比赛取消(CANCEL),编写程序顺序输出这四种情况。
  • 分析:

比赛结果只有四种可能,可以声明一个枚举类型。

#include <iostream>

using namespace std;

enum GameResult {WIN, LOSE, TIE, CANCEL};

int main() {

GameResult result;

enum GameResult omit = CANCEL;

for (int count = WIN; count <= CANCEL; count++) {

  result = GameResult(count);

  if (result == omit) 

    cout << "The game was cancelled" << endl;

  else {

    cout << "The game was played ";

    if (result == WIN)      cout << "and we won!";

    if (result == LOSE)       cout << "and we lost.";

    cout << endl;

  }

}

return 0;

}

 

auto类型与decltype类型

  • auto:编译器通过初始值自动推断变量的类型
    • 例如:auto val = val1 + val2;

如果val1+val2是int类型,则val是int类型;

如果val1+val2是double类型,则val是double类型。

  • decltype:定义一个变量与某一表达式的类型相同,但并不用该表达式初始化变量
    • 例如:decltype(i) j = 2;

 

 

 

 
posted @ 2015-12-28 16:10  董文博  阅读(407)  评论(0编辑  收藏  举报