Chap2-6 Structured Programming

Structured Programming


(结构化编程)

Data Structure


(数据结构)

Literal constant(文字常量)


i = 255;

area = r * r * 3.14;

for(i = 0; i < 80; i++){
    ...
}

magic number (幻数)

Symbol constant(符号常量)

#define PI 3.14
#define MaxChar 80

Named Constant(命名常量/常变量)

const float PI = 3.14;
const short int MaxChar = 80;

基本数据类型

int sum, area, i=0 ;
char c1='a', c2='b', c3=61 ;

float x, y, x ;
double pi(3.14);

新引入的bool型(布尔型/逻辑型)

bool isDead = true;
isDead = false;

isDead = 0 ;
isDead = 1 ;
isDead = 100 ;

if ( isDead ) {...}
if ( !isDead && isRich ) {...}

enum(枚举类型)

定义:

enum  weekday{
    SUN, MON, TUE, WED, THU, FRI, SAT
};

enum city{
    Beijing,Shanghai,Tianjin=5,Chongqing
};

使用枚举类型定义变量:

enum  city  city1, city2;
city  city1, city2; //省略enum

//同时定义类型及变量
enum city{
    Beijing,Shanghai,Tianjin=5,Chongqing
} city1, city2;

枚举类型变量的赋值:

weekday d1,d2,d3,d4;
d1=SUN;
d2=6;            //错误
d3=Shanghai;     //错误

在条件表达式中:

if( city1 == 3 );
if( d1 > SUN );

array(数组)

定义:

int a[5];
int m[2][3];

用字符进行初始化:

char s1[ ]={'C','h','i','n','a'};
char s2[ ][4] = {
    {'H','o','w'},
    {'a','r','e'},
    {'y','o','u'}
};

用字符串进行初始化:

char s3[ ] = "China";
char s4[ ][4] = {"how", "are", "you"};

struct(结构)

定义:

struct student
{
    long no,birthday;   //学号,生日
    char name[22];      //姓名
    char sex;         //性别 1或0 分别代表男或女
    float score;        //成绩
};

联合

union UnionData
{
    char       Ch;
    short      Sint;
    long       Lint;
    unsigned   Uint;
    float       f;
    double     d;
    char       str[10]
};

指针

指针(变量)定义与初始化:

int x=100;

1)  int  *ip ;
    ip = &x ;
    
2)  int *ip = &x ;

指针运算:

*ip = 200 ;

ip++;

ip = ip - 10 ;

ip += 10 ;

offset = ip1 - ip2 ;

if ( ip1 > ip2 ) {......};

void型指针:

void *vp ;

int n = 100 ;

vp = &n ;

cout << * ( int * ) vp ;


int *ip ;

ip = ( int * ) vp ;

指针与字符串:

char str[5] = “abcd” ;

char *p_str = “abcd” ;

指针与数组:

cout << *str ; //将输出什么?

cout << *( str+2 ) ; // ?

cout << p_str[3] ; // ?

p_str = str ;

二(多)重指针:

int **p ;

(int *) *p ;

动态内存分配

C:

char * p = (char *) malloc ( 100 ) ;

strcpy ( p , ”Hello World!” ) ;
    ...
free ( p ) ;

C++:

int *p ;

p = new int ;

*p = 50 ;   // p = new int( 50 ) ;

delete p ;

C++:

int *p = new int[100] ;

if( p == NULL ) {

    cout<<“内存分配失败!” ;
    
} else {

    for ( int i=0 ; i < 100; i++ ){
    
        p[ i ] = i ;
        
    }
    ... ...
    delete []p ;
}

多维数组动态分配:

int ( *p ) [5][6] ;

p = new int [3][5][6];

int x = 4 ;

p1 = new int [x][5][6];

p2 = new int[3][x][6] ;  //错误

函数指针

int add ( int a , int b ) ; //普通函数

int ( *fptr ) ( int a , int b ) ; //定义函数指针

fptr = add ;     // 给函数指针赋值,或fptr = &add

add ( 1 , 2 ) ;

( *fptr ) ( 1 , 2 ) ; //用指向函数的指针调用函数add

fptr ( 1 , 2 ) ;      //用指向函数的指针调用函数add

指针常量与常量指针

指针常量: (指针本身是常量):

int a = 100 ;

int * const p = &a;

常量指针: (指向常量的指针)

const int a = 100 ;

const int * p = &a;// 或者 int const * p = &a;

指向常量的常量指针: (都是常量)

const int a = 100 ;

const int * const  p = &a;
// 或者
int const * const p = &a;

类型转换

自动转换

int n = 10 ;
char c = 20 ;

n = c ;

c = n ;

强制转换

int  n ;
float x = 8.57 ;

n = ( int ) x ;

x = ( float ) n ;

Control Structure


(控制结构)

单分支

if ( score > 100 ) score = 100 ;
if ( score > 100 ) { score = 100 ;  }
if ( score > 100 )
    score = 100 ;
if ( score > 100 ) {
    score = 100;
}

if else

if ( x > y ) cout << x ;
else cout << y;

可以更简单吗?

cout << (x > y)? x:y ;

if else if

if( n >= 60 )
    if ( n>= 90 ) cout << "A";
    else if ( n >= 80 ) cout << "B";
        else cout << "C";
else cout << "D";

if else if

if( n >= 60 ){
    if ( n>= 90 ){
        cout << "A";
    }
    else{
        if ( n >= 80 ){
            cout << "B";
        }
        else{
            cout << "C";
        }
    }
}
else{
    cout << "D";
}

多分支

switch ( n/10 ){
    case 10:
    case 9:
        cout << “A” ;
        break;
    case 8:
        cout << “B” ;
        break;
    case 7:
    case 6:
        cout << “C” ;
        break;
    default:
        cout << “D” ;
}

入口条件循环(while)

int  i = 1;
int  sum = 0 ;

while ( i <= 100 ) {
    sum += i++ ;
}

出口条件循环(do while)

int  i = 1;
int  sum = 0 ;

do {
    sum += i++ ;
}while ( i <= 100 )

for循环

int  sum = 0 ;

for ( int i=1; i <= 100;i++ ) {
    sum += i ;
}

嵌套for循环

for ( int i=1; i <= 9; i++ ) {

   for(int j=1;  j<=i ;  j++){
       cout <<j<<“x”<<i<<“=“ <<j * i<< “\t”;
   }
   
   cout << endl;
}

break语句

int i , n ;
cin >> n ;

for ( i=2; i < n;i++ ) {
    if ( n%i == 0 ) break;
}

if ( i >= n ) cout << n << “是素数” ;
else cout << n << “不是素数” ;

此处,不用break,可以吗?

for ( i=2; i < n, n%i !=0;i++ ) ;

while + break

int i , n ;
while(1){
    cin >> n ;
    if ( n <= 1 ) break ;
    
    for ( i=2; i < n, n%i !=0;i++ ) ;
    
    cout << n << i >= n ? “是”:“不是” << "素数";
}

while + break + continue

int i , n ;
while(1){
    cin >> n ;
    
    if ( n <= 0 ) break ;
    if ( 1 == n ) continue ;
    
    for ( i=2; i < n, n%i !=0;i++ ) ;
    
    cout << n << i >= n ? “是”:“不是” << "素数";
}

function


(函数)

一个简单例子

#include <iostream>
using namespace std;

int max( int x , int y )
{
    return ( x>y ) ? x : y;
}

void main()
{
    int a , b ;
    
    cin >> a >> b ;
    cout << max( a , b ) << endl ;
    
    cin >> a >> b ;
    cout << max( a , b ) << endl ;
}

函数prototype(原型)

#include <iostream>
using namespace std;

int max( int x , int y );

void main()
{
    int a , b ;
    cin >> a >> b ;
    cout << max( a , b ) << endl ;
}

int max( int x , int y )
{
    return ( x>y ) ? x : y;
}

递归

//求 n!

int fac( int n )
{
    return  1==n ? 1 :  n * fac( n-1 ) ;
}

void main()
{
    cout << fac( 3 );
}

【课堂练习2-1】p79 汉诺塔

函数调用及传参的原理

观察下面的代码:

void swap ( int x , int y );

void main ( ) {
    int x = 10 , y = 20 ;
    swap( x , y ) ;
}

void swap ( int x , int y ) {
    int  temp = x ;
    x = y ;
    y = temp ;
}

传指针参数:

void swap ( int* x , int* y );

void main ( ) {
    int x = 10 , y = 20 ;
    swap( &x , &y ) ;
}

void swap ( int* x , int* y ) {
    int  temp = *x ;
    *x = *y ;
    *y = temp ;
}

传Reference(引用)参数:

void swap ( int & x , int  & y );

void main ( ) {
    int x = 10 , y = 20 ;
    swap( x , y ) ;
}

void swap ( int & x , int  & y ) {
    int  temp = x ;
    x = y;
    y = temp;
}

独立引用


int  x = 100 ;
int & r = x ;

r = 200 ;
x = 300 ;

函数返回类型为引用(1)


int maxValue ( int a [ ] ,  int  n ) {
    int  t = 0 ;
    for ( int i = 0 ;  i < n ;  i++ ){
        if ( a[ i ] > a[ t ] ) t = i ;
    }
    return a[ t ] ;
}

int& maxItem ( int a [ ] ,  int  n ) {
    int  t = 0 ;
    for ( int i = 0 ;  i < n ;  i++ ){
        if ( a[ i ] > a[ t ] ) t = i ;
    }
    return a[ t ] ;
}

函数返回类型为引用(2)


int  a[ 5 ] = { 1, 2, 3, 4, 5 } ;

int m1 = maxValue ( a , 5 ) ;

int &m2 = maxItem( a , 5 ) ;
m3 = 100 ;

maxItem( a , 5 ) = 200 ;

int m3 = maxItem( a , 5 ) ;
m2 = 300 ;

利用宏定义避免函数的调用开销

#define max( x , y ) ( (x)>(y) ? (x) : (y) );

void main()
{
    int a , b ;
    cin >> a >> b ;
    cout << max( a , b ) << endl ;
}

default(默认)实参

void drawCircle( int x, int y, int r,
    int color )
{
    ...
}

void main()
{
    drawCircle( 0 , 0 , 1 , BLACK ) ;
    drawCircle( 2 , 1 , 2 , BLACK ) ;
    drawCircle( 3 , 0 , 3 , RED ) ;
    drawCircle( 4 , 3 , 4 , BLACK ) ;
}

default(默认)实参

void drawCircle( int x, int y, int r,
    int color = BLACK )
{
    ...
}

void main()
{
    drawCircle( 0 , 0 , 1 ) ;
    drawCircle( 2 , 1 , 2 ) ;
    drawCircle( 3 , 0 , 3 , RED ) ;
    drawCircle( 4 , 3 , 4 ) ;
}

默认值必须在最后,why?

C语言中功能相同(参数不同)的函数

//原型:
int max2int ( int x , int y ) ;
int max3int ( int x , int y , int z ) ;

float max2float ( float x , float y ) ;

//调用:
n = max2int ( 1 , 2 ) ;
n = max3int ( 1 , 2 , 3 ) ;

f = max2float ( 1.0 , 2.0 ) ;

C++ : overload(函数重载)

原型:
int max ( int x , int y ) ;
int max ( int x , int y , int z ) ;

float max ( float x , float y ) ;

调用:
n = max ( 1 , 2 ) ;
n = max ( 1 , 2 , 3 ) ;

f = max ( 1.0 , 2.0 ) ;

【作业2-2】


chap4( P95 ):


5(1),5(5),5(7)

需调试通过,并提交到github

作用域 & 生命期


  • 作用域:
    • 全局:
      • 文件作用域
    • 局部:
      • 函数作用域
      • 块作用域
      • 函数原型作用域
  • 生命期:
    • 静态
    • 动态

【例2-1】电脑入库及销售


1)查看库存
2)电脑入库
3)卖出
4)退出程序

【代码】菜单显示

cout<<"1)查看库存"<<endl;
cout<<"2)电脑入库"<<endl;
cout<<"3)售出"<<endl;
cout<<"4)退出程序"<<endl;

【代码】菜单选择

cin>>action;
switch(action){
case 1:
    list();
    break;
case 2:
    enterWarehouse();
    break;
case 3:
    outWarehouse();
    break;
case 4:
    return 0;
default:
    cout<<"您输入了错误的菜单项,请重新选择!";
}

【代码】主循环

do{
    ...
    case 3:
        outWarehouse();
        break;
    case 4:
        return 0;
    ...
}while(1);

【代码】list 显示库存信息

void list(){

    cout<<"型号\t"<<"数量"<<endl;
    
    for(int i=0;i<modelCount;i++){
    
        cout<<computers[i].model<<"\t"
        
        cout<<computers[i].total<<endl;
    }
}

【代码】Computer数据结构定义

int modelCount = 0;

struct Computer{

    char model[20];
    
    int total;
    
}computers[100];

【代码】enterWarehouse 入库

void enterWarehouse(){
    struct Computer computer;
    cout<<"型号:";
    cin>>computer.model;
    cout<<"数量:";
    cin>>computer.total;
    
    int i = find(computer.model);
    if(i == modelCount){
        strcpy(computers[i].model,computer.model);
        computers[i].total = computer.total;
        modelCount++;
    }else{
        computers[i].total += computer.total;
    }
}

【代码】find 按型号查找

int find(char* model){
   int i;
   for(i=0;i<modelCount;i++){
      if(strcmp(computers[i].model,model)==0){
         break;
      }
   }
   return i;
}

【代码】outWarehouse 出库

void outWarehouse(){
    struct Computer computer;
    cout<<"型号:";
    cin>>computer.model;
    cout<<"数量:";
    cin>>computer.total;
    
    int i = find(computer.model);
    if(i == modelCount){
        cout<<"型号错误!"<<endl;
    }else{
        computers[i].total -= computer.total;
    }
}

【代码】outWarehouse 优化

void outWarehouse(){
    struct Computer computer;
    
    input(computer);
    
    int i = find(computer.model);
    
    if(i == modelCount){
        cout<<"型号错误!"<<endl;
    }else{
        computers[i].total -= computer.total;
    }
}

【代码】input 输入一个computer的信息

void input(struct Computer computer){

    cout<<"型号:";
    cin>>computer.model;
    
    cout<<"数量:";
    cin>>computer.total;
}

???

【代码】input fix(修复)bug 的版本

void input(struct Computer &computer){

    cout<<"型号:";
    cin>>computer.model;
    
    cout<<"数量:";
    cin>>computer.total;
}

【作业2-3】C++考试成绩管理


基本功能:
    1)查看学生名单(含所有信息)
    2)选课(添加学生)
    3)退选(删除学生)
    4)录入成绩(从特定学号开始,每录入完一人,询问是否继续)
    5)退出程序
选做:支持录入多门课程

The End

目录