现在的位置: 首页 > 综合 > 正文

《C++案例指导》(3)C++流程控制、自定义数据类型

2013年04月11日 ⁄ 综合 ⁄ 共 6256字 ⁄ 字号 评论关闭

C++流程控制语句中主要分两大块:选择语句(if语句和switch语句)和循环语句(while语句、do-while语句和for语句)。

if语句和循环语句太简单,就不啰嗦了。直接进入switch语句,在进行判断选择的时候,有可能每次都是对同一个表达式的值进行判断,那么就没有必要在每一个嵌套的if语句里都计算一下它的值,而是使用switch来解决这个问题。语法形式为:

      switch (表达式)
      {
          case
常量表达式1: 语句1
          case
常量表达式2: 语句2
          
……

          case 常量表达式n: 语句n
          default:          
语句n+1
      }   

      此类语句的执行顺序是,先计算表达式的值,然后在case语句中寻找与之相等的常量表达式,跳到此处开始执行,若没有与之相等的则跳到default开始执行。使用switch语句时要注意以下几点:这些常量表达式的值不能相同顺序可以随便;每个case语句的最后最好加break语句,不然会一直把下面所有的语句执行完;switch括号里的表达式必须是整型、字符型和枚举型的一种;每个case下的语句不需要加{};如果多个case下执行一样的操作,则多个case可以共用一组语句,比如
       case 1:
       case 2:
       case3:   a++;
                    break;
虽然说每个case语句之后加上一句break;比较好,但是也有例外的时候,如下案例指导

案例指导:根据输入的月份计算出从年初到本月底的天数


代码注解

#include
<iostream>

using
namespace
std;

int main()

{

     int year,month,days = 0;

     cout <<"Input year and month:";

     cin>>year>>month;

     switch(month)

     {

     case 12 : days += 31;

     case 11 : days += 30;

     case 10 : days += 31;

     case 9  : days += 30;

     case 8  : days += 31;

     case 7  : days += 31;

     case 6  : days += 30;

     case 5  : days += 31;

     case 4  : days += 30;

     case 3  : days += 31;

     case 2  :

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

            days += 29;

        else

            days += 28;

     case 1  : days += 31;

     }

     if(0 == days)

        cout<<"Wrong month "<<endl;

     else

        cout<<"Total days is :"<<days<<endl;

    return (0);

}

思考与提高

这里使用不带break的case语句,刚好依次累加各月的天数。case分支中的if语句是用来判断用户输入的年份是否是闰年。某年是闰年的条件是:该年能够被4整除但是不能被100整除,或者能够被400整除。所以是否需要加入break语句 还是按具体情况来分析,不要不加分析地直接加上break语句。另外在循环中经常用过两个函数exit()函数和abort()函数。exit()函数和abort()函数是C++语言中的库函数,作用都是终止整个程序的运行,将控制权返还给系统。为了能够使用这两个函数,必须在程序头添加头文件<cstdlib>.

charintfloat等数据类型,这些都是C++内置的基本数据类型,但这些数据类型还不能完全满足实际编程的需求,需要我们自己定义一些数据类型使用。自定义数据类型有:枚举类型、结构类型、联合类型、数组类型和类类型等。

类型定义语句typedef的语法形式

typedef 已有类型名  
新类型名表


[]使用类型定义语句typedef并不能创建一种新的数据类型,只是为一个已经存在的类型定义一个新的名字。类型定义主要是为了改善程序的可读性和简化程序的书写。

枚举类型的声明形式

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

结构体声明形式

struct  结构体名

        {

               数据类型  成员名 1

               数据类型  成员名 2 

            ……

               数据类型  成员名 n

        };

结构体类型变量声明的语法形式

结构名  结构体变量名;

结构体成员的引用形式

结构体变量名.成员名

联合体声明的语法形式

union 联合名

       {

               数据类型    成员名 1

               数据类型    成员名 2

……

                数据类型    
成员名 n

       };

联合体的变量声明和成员的引用和结构体一样。

下面来深入理解枚举类型、结构体类型和联合类型

1.枚举类型

在现实当中经常遇到这种情况,描述一件事情时只能取几个有限的值,比如,一周只有星期一、星期二...星期日七天,比赛结果只有胜、负、平和比赛取消等四种结果。我们可以用06的整数表示星期一到星期日,7,8,9等都不是合法数据,如果我们用整数来表示星期几那就需要专门判断下是不是在06之间,但是如果用枚举类型定义就没有这种问题,因为枚举类型就那几个可能的值。

枚举类型的声明形式为: enum 
枚举类型名   { 
变量值列表 }

变量值列表里都是整型变量,另外不要忘记最后面的分号

比如,enum weekday   { sun,mon,tue,wed,thu,fri,sat };

这里的枚举元素sunmon...都没有指定值,它们就使用默认值,依次为0,1,2...。即sun就是0mon就是1...sat6。也可以在声明枚举类型时指定枚举元素的值,比如enum 
weekday  { sun=7, mon=1,tue, wed, thu, fri, sat };

这里sun就是7mon1,后面的值在mon的基础上依次加1,即tue等于2wed3...sat6。枚举元素按常量处理,不能对它们赋值除了声明的时候,像sun=0;这样的语句就是非法的。

 枚举类型我们声明了以后就能像intfloat等类型那样用了,可以定义枚举类型的变量。整数值需要赋给枚举变量时,应进行强制类型转换。

例如:设某次体育比赛的结果有四种可能:胜(win)、负(lose)、平局(tie)、比赛取消(cancel),编写程序顺序输出这四种情况。分析:由于比赛结果只有四种可能,所以可以声明一个枚举类型,声明一个枚举类型的变量来存放比赛结果。    

       #include<iostream>

       using namespace std;

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


       int _tmain(int argc, _TCHAR* argv[])

       {

               game_result  result;                                          //
声明变量时,可以不写关键字enum

               enum  game_result  omit =CANCEL;            //
也可以在类型名前写上关键字enum

               int count;

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

               {

                         result = (game_result)count;

                         if (result == omit)

                          {

                                   cout << "The game was cancelled\n";

                          }

                         else

                         {

                                    cout<< "The game was played ";

                                    if(result == WIN)  

                                               cout << "and we won!";

                                   if (result == LOSE) 

                                               cout << "and we lost.";

                                   cout << "\n";

                         }

               }

               return 0;

        }

        运行结果是: 

                         The game was played and we won!

                         The game was played and we lost.

                          Thegame was played

                         The game was cancelled

 2.结构体

有时候我们需要将一些不同类型的数据组合成一个整体,例如,一个学生的学号、姓名、年龄和成绩等,它们数据类型不同,但都属于一个人。这就要用到结构体。一个学生的结构体可以定义成如下形式:      

        structstudent   //学生信息结构体

        {

               int        num; //学号

               char    name[20]; //姓名

               char    sex; //性别

               int        age; //年龄

               float     score; //成绩

               char     addr[30]; //住址

       };

定义了结构体类型,我们就可以用它来定义结构体变量,就像int a;那样。结构体型变量的定义形式也类似int等类型: 
结构体类型名  
结构体变量名;。比如,定义一个上面的那个结构体变量,student  s;。可以像这样声明了结构体类型以后再定义结构体变量,也可以把它们放在一起。结构体变量占用内存的大小可以用sizeof(结构体类型名或变量名)计算。在定义结构体变量时可以直接赋初值。结构体成员的使用形式是:结构体变量名.成员名。

 3.联合体

有的时候需要几个不同类型的变量共用一组内存单元,这时就需要用联合体。

 例如: 

       union uarea

       { 

                char    c_data;

                short   s_data;

                long     l_data;

       }

       联合体类型在内存中是怎样占用内存单元的呢?联合体占用的内存大小是其占内存最大的成员需要的内存大小,就像上边的uarea,它占用的内存大小就是最大成员long需要的4个字节。联合体里同时只能放一个成员的值。uareac_datac_data占用第一个字节,放s_datas_data占用前两个字节,放l_datal_data占用全部的4个字节。

联合体也可以没有名称,叫做无名联合体。无名联合体只是声明一个成员项的集合,这些成员有相同的内存地址,可以用成员项的名字直接访问

例如:

       union

       {   

               int      i;

               float   f;

       }

       在程序中可以直接用成员项if的名字访问if,比如i=2;
f=3.2;

      例如:

    #include <iostream>
       using namespace std;

       unionmyun
       {
               int   k;

               struct { int x; int y; int z; }u;
       }a;
       int _tmain(int argc, _TCHAR* argv[])

       {
               a.u.x=4;
               a.u.y=5;
              a.u.z =6;
              a.k = 0;
              cout<<a.u.x<<" "<<a.u.y<<""<<a.u.z<<" ";

              return 0;
       }

      这个程序输出0 56。为什么呢?不应该是4,5,6?
因为联合体的成员共用内存,所以a.u.x占用的内存里的4被后来的a.k覆盖了,变成了0

综合案例指导:百钱买百鸡


案例说明

公鸡一只值5钱,母鸡一只值3钱,三只小鸡值1钱,现有100钱,需买100鸡,问公鸡,母鸡和小鸡各多少只?

案例解析

分别用i ,j ,k 表示公鸡、母鸡和小鸡的数量,采用穷举法找出满足条件

(n == 5*i +3*j  + k / 3)&&(0 == k % 3)&&(n== i + j + k)的所有组合。

代码解析

#include
<iostream>

#include
<iomanip>

using
namespace
std;

int main()

{

     int n = 100;

     cout<<setw(3)<<"公鸡"<<setw(6)<<"母鸡"<<setw(6)<<"小鸡"<<endl;

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

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

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

               if((n == 5*i + 3*j + k /3)&&(0 == k%3)&&(n== i + j + k))

                   cout<<setw(3)<<i<<setw(5)<<j<<setw(5)<<k<<endl;

    return (0);

}

运行与调试

公鸡 
母鸡 
小鸡

  4  18   78

  8  11   81

 12   4   84

 

抱歉!评论已关闭.