C++学习代码笔记

变量、输入输出

/**
 *文件名:main.cpp
 *描述:c++学习笔记(第一、二章)(网易云课堂 课时1——课时25)
 *作者:li
 *时间:2020.1.2
 *版权:

 */

////第一章节
#include <iostream>
#include <cstdio>     //c语言中的库,去掉.h,前边加c,都可以用
#include <cmath>
#include<iomanip>
#include <windows.h>
//
using namespace std;  //命名空间 standard
//
//int main()
//{
//    cout << "Hello world!" << endl;//endl = end line (\n) endl 还会清空缓冲区
//    cout << "hi" << endl;
//    return 0;
//}
//



////输出练习
//#include <iostream>
//using namespace std;
//int main()
//{
//    //输出对象
//    cout << "英雄名称:寒冰射手\n";
//    cout << "伤害: 56\t 攻击距离:600\n"
//         << "护甲: 15.5 \t 魔抗:30\n"
//         << "生命值:395 \t 生命恢复:0.9\n";
//    return 0;
//
//}




////第二章
//
////变量:命名规则
//
////输出整形的最大值
//#include<iostream>
//using namespace std;
//
//int main()
//{
//    cout << INT_MAX << endl;
//    return 0;
//}
//
////short int 使用短整型,一定要慎重


//int  main()
//{
//    const float PI = 3.14f;   //定义了一个float类型的常量
//
//    //PI = 3.15   ////错误语句。const定义的常量不能被修改
//
//    float radius = 4.5;
//    float height = 90.0f;
//    double volume = PI * pow(radius,2);
//    cout << "体积是:"
//    return 0;
//}
//

//#include<iomanip>
//int main()
//
//{
//    //输出double类型数据
//    //控制以小数的方式显示,
//    cout << fixed;
//
//    //控制显示的精度
//    cout << setprecision(2);  // #include<iomanip>
//    double doubleNum = 10.0 / 3.0;
//    cout << doubleNum << endl;
//    return 0;
//}
//
//
//int main()
//{
////    //sizeof 用来测量数据类型的程度
////    cout << sizeof(double) <<endl;
////    cout << sizeof(long double) << endl;
////    cout << sizeof(3.14f) << endl;
////    return 0;
//
//
//
//
////演示双精度浮点型和单精度浮点型的精度
////cout里默认显示小数点后六位数字
//
//
//    float numFloat = 10 / 3.0;
//    double numDouble = 10 / 3.0;
//
//    cout << fixed;  //让浮点型固定以数字的方式显示
//    cout << setprecision(2); //控制显示的小数位数
//    cout << "numFloat = " << numFloat << endl;
//    cout << "numDouble =" << numDouble <<endl;
//
//    cout << "numFloat = " << numFloat * 1000000 << endl;
//    cout << "numDouble =" << numDouble * 100000 <<endl;
//
//    //可以看出float精度损失
//
//    return 0;
//
//}




////cin cout 的使用
//int main()
//{
//    SetConsoleTitle("示例:打印德玛西亚之力的详细信息");
//    /**  伤害  */
//    double value_attack = 57.88;
//    /**  伤害成长值  */
//    double value_attack_growth = 4.5;
//    /**  攻击距离  */
//    double value_attack_distance = 172;
//    /**  护甲值  */
//    double value_defence = 27.54;
//    /**  护甲成长值  */
//    double value_defence_growth = 3.0;
//
//
//
//    cout << "名称:德玛西亚之力" << endl;
//    cout << "伤害:" << value_attack << "(+" << value_attack_growth << ")\t"
//         << "攻击距离:" << value_attack_distance << endl;
//
//        ////
//        return 0;
//}




//char 类型是8位
//1 1111111
//(100000000 - 1 + 1)




//int main()
//{
//    cout << CHAR_MIN << '\t' << CHAR_MAX << endl;
//    cout << UCHAR_MAX<< endl;
//
//    return 0;
//}



//int main()
//{
//
//    cout << 'A' + ' '<< endl;
//    return 0;
//}


//
//int main()
//{
//    int num;
////    char ch;
//    char ch1,ch2,ch3;
//    cout << "请输入:";
////    cin >> num;
////    cin >> ch;
//    cin >> ch1 >> ch2 >> ch3 ;
//    //假设用户输入123abc
////    cout << num << "\t" << ch << endl;
//    cout << ch1 << ch2 << ch3 << endl;
//
//}





//
//int main()
//{
//    string str = "你好";
//    char names[] = "你好";
//    cout << str << endl;
//}



//int main()
//{
//    double attack1 = 272;
//    double attack2 = 250;
//    double attack3 = 240;
//
//    cout << left;       //左对齐,去掉这条语句默认右对齐
//    cout << setfill('_');       //填充
//
//    cout << setw(8) << attack1 <<       //#include <iomanip>
//            setw(8) << attack2 <<
//            setw(8) << attack3 << endl;
//
//}




//int main()
//{
//
//    int num1 = 5,num2 = 2;
////    cout << num1 / num2 << endl;
//
//
//}




//面向对象和面向过程

 

运算与循环

//#include <iostream>
//#include <iomanip>
//using namespace std;
//int main()
//{
//    char pan = '\0';  //默认值设置为空字符
//    cout << "请输入一个字符,我来判断是否合法" << endl;
//    cin >> pan;
//    //'A' ~ 'Z'
//    if(pan>='A' && pan<='Z') //if(pan>=65 && pan<=65 + 26)
//        {
//            cout << "这是一个合法的盘符!" << endl;
//        }
//    else
//    {
//        cout << "这不是一个合法的盘符" << endl;
//    }
//}
//


////#include <iostream>
////#include <iomanip>
////using namespace std;
////int main()
////{
////    double price_louis = 35000.0;
////    double price_hemes = 11044.5;
////    double price_chanel = 1535.0;
////    //如果总价大于5万就打七折,否则打九折
////    double total = 0;
////    double zhekou = 0;
////    if(total > 500000)
////    {
////        zhekou = 0.7;
////    }
////    else
////    {
////        zhekou = 0.9;
////    }
////    total = price_louis+price_chanel+price_hemes;
////    cout << "您消费的金额是:" << total << endl;
////    return 0;
////
////}
////
//


//
//#include<iostream>
//using namespace std;
//
//int main()
//{
//    int a = 5, b = 10;
//    if(a > b)
//    if(a++ > --b)
//        a += b;
//    cout << a << '\t' << endl;
//}
//


//
//#include<iostream>
//using namespace std;
//
//int main()
//{
//    int num = 5;
//    cout << sizeof(num++) << endl;  //seizeof 是一个运算符,不会进行里边的运算
//    cout << num << endl;
//    return 0;
//}




//
//#include <iostream>
//using namespace std;
//
//int main()
//{
//
//    int i = 1;
//    while(i <= 10000)
//
//        {
//            cout << "测试" << endl;
//            i++;
//        }
//}
//



//#include<iostream>
//using namespace std;
//
//int main()
//{
//
//    int num = 1;  //循环次数
//    int sum = 0;  //保存累加和
//    while(num <= 100)
//    {
//        num++;
//        sum = sum + num;
//
//    }cout << sum << endl;
//}
//




////////////代码有问题,等待调试
//
//
//#include <iostream>
//#include <cstdlib>
//using namespace std;
//
//int main()
//{
//    int i = 0;
//    string password;
//    if(i<3)
//    {
//        cout << "Please Enter your code" << endl;
//        cin >> password;
//        if(password == "123456")
//        {
//            cout << "Right!";
//        }
//        else
//        {
//            cout << "Wrong!";
//            i += 1;
//        }
//
//    }
//
//    else
//    {
//        cout << "You hava enter wrong codes for three times ,and system will quit!"<<endl;
//        exit(404);
//    }
//}


//
//
//#include<iostream>
//#include<cmath>
//using namespace std;
//
//int main()
//{
//    //某宝双十一2015年的交易额是800亿,每年递增25%
//    //问:按此速度,哪年的交易额达到20000亿
//    //1.寻找循环变量 初值、判断、更新
//    //年  交易额  递增比
//    double money = 800;
//    money = 800;
//    int n;
//    for(n=1;money<2000;n++)
//    {
//        money = 800 * pow(1.25,n);
//        cout << 2015+n << "达到" << money << endl;
//    }
//
//     ////cout << 2015+n <<endl;  //如果把输出加到这里,会导致年数多一年
//     ////使用while循环可以解决这个问题
//     return 0;
//}
//
//
//


//
//#include <iostream>
//using namespace std;
//
//int main()
//{
////    int k = 1, n = 10, m = 1;
////    while(k<=n)
////    {
////        m*=2;
////        n--;
////    }
////    cout << m;
//
//
//        int k = 2;
//        while(k=1)   //无论k是什么值,此处被赋值为1,该循环为死循环
//            k=k-1;
//        cout << "I am here" << endl;
//}

//
//
//
//#include<iostream>
//#include<cstdlib>
//#include<ctime>
// using namespace std;
//
// int main()
// {
//
//     //循环
//     int hp1 = 100;
//     int hp2 = 100;
//
//     int attack1 = 0;  //巴神
//     int attack2 = 0;  //草薙京
//     int randNum;      //用来存放玩家攻击顺序的随机变量
//
//     //1.模拟玩家出招:可以采用随机数是奇数/偶数的方式来决定谁先出招
//     //奇数 巴神先   偶数 草薙京先
//     srand(time(NULL));
//
//     while(hp1 >= 0 && hp2 >= 0)
//     {
//         randNum = rand();
//     if(randNum % 2 == 1)  //奇数
//     {
//         attack1 = (int)(5+10 * rand() / (RAND_MAX + 1.0));
//         attack2 = (int)(5+10 * rand() / (RAND_MAX + 1.0));
//
//         hp2 -= attack1; //互相掉血
//         hp1 -= attack2;
//     }
//     else   //偶数
//     {
//         attack2 = (int)(5+10 * rand() / (RAND_MAX + 1.0));
//        attack1 = (int)(5+10 * rand() / (RAND_MAX + 1.0));
//
//        hp1 -= attack1;
//        hp2 -= attack2;
//     }
//
//     }
//     //打印结果
//     cout << "八神庵HP:" << hp1 << endl;
//     cout << "草薙京HP:" << hp2 << endl;
// }



// #include <iostream>
// using namespace std;
//
// int main()
//{
//
//    int i;  //第i个月
//    double salary;
//    double total;
//
//
//    for(i=1;i<7;i++)
//    {
//        cout << "请输入您第" << i << "个月的工资" << endl;
//        cin >> salary;
//        total += salary;
//    }
//
//     cout << "您六个月的平均工资是" << total /6 << "元" << endl;
//     return 0;
//}


//
//
////有问题,需要修正
//#include<iostream>
//using namespace std;
//
//
//int main()
//{
//    //请使用循环打印1997年7月的月历
//    //已知:1997年7月1日(星期二),香港回归举国同庆
//    //1.定义变量
//    //2.书写循环
//    //3.书写循环体及循环体内的条件
//    int days = 31; //7月一共有31天
//    int week = 2;
//    cout << "一\t二\t三\t四\t五\t六\t日\n" << endl;
//    //打印前边的那个/t     周几 - 1
//    for(int i = 0;i < week - 1; i++)
//    {
//        cout << '\t';
//    }
//
//
//    //第二个for循环用来打印日期,因为7月有31天,所以循环31次
//    for(int i = 0;i <= 31;i++)
//    {
//        cout << i+1 << '\t';
//        //经过观察,\t和\n是有规律的
//        //规律:星期日是\n,其他日子就是\t
//        if((i + week) % 7 == 0)
//        {
//            cout <<'\n';
//        }
//        else
//        {
//            cout << '\t';
//        }
//    }
//    return 0;
//
//}


////输入玩家年龄,如果为负,程序退出
//#include <iostream>
//using namespace std;
//
//int main()
//{
//    int age;
//    for(;;)
//    {
//    cout << "请输入玩家年龄" << endl;
//    cin >> age ;
//    if (age < 0)
//    break;
//    }
//    cout << "程序结束!!!!!" << endl;
//}
//
//
//



//
/////幸运53猜商品价格
/////根据猜对的次数给与不同的奖励
/////1次 iPhone Plus 土豪金
/////2——3次 小米移动充电源
/////5次以内 VR眼镜
//#include<iostream>
//using namespace std;
//
//int main()
//{
//    const double price = 5000.0;  //要猜测的商品价格,可以设置为随机数字
//    double guess_price;   //用户猜的商品价格
//    int guess_count = 0;   //用户猜测的次数
//
//    //游戏实际上就是一个死循环
//    for(;;)
//    {
//        guess_count++;
//        cout << "请输入神秘商品的价格:" ;
//        cin >> guess_price;
//        if(guess_price > price)
//        {
//            cout << "猜大了!" << endl;
//        }
//        else if(guess_price < price )
//        {
//            cout << "猜小了!" << endl;
//        }
//        else
//        {
//            cout <<"恭喜,猜对了" << endl;
//            break;
//        }
//    }
//    if(guess_count == 1)
//      {
//          cout << "获得Iphone 8 Plus大奖!";
//      }
//      else if(guess_count >= 2 && guess_count <= 3)
//      {
//          cout << "获得小米移动电源!" << endl;
//      }
//      else if(guess_count >= 4 && guess_count <= 5)
//      {
//          cout << "获得VR眼镜!" << endl;
//      }
//      else
//      {
//          cout << "获得幸运奖" << endl;
//      }
//
//
//}
//
//
//
//#include <iostream>
//using namespace std;
//
//int main()
//{
////    int k = 1, n = 10, m = 1;
////    while(k<=n)
////    {
////        m*=2;
////        n--;
////    }
////    cout << m;
//
//
//        int k = 2;
//        while(k=1)   //无论k是什么值,此处被赋值为1,该循环为死循环
//            k=k-1;
//        cout << "I am here" << endl;
//}



//
//#include<iostream>
//using namespace std;
//
//
//int main()
//{
//    //请使用循环打印1997年7月的月历
//    //已知:1997年7月1日(星期二),香港回归举国同庆
//    //1.定义变量
//    //2.书写循环
//    //3.书写循环体及循环体内的条件
//    int days = 31; //7月一共有31天
//    int week = 2;
//    cout << "一\t二\t三\t四\t五\t六\t日" << endl;
//    //打印 /t     周几 - 1
//    for(int i = 0;i < week - 1; i++)
//    {
//        cout << '\t';
//    }
//
//    cout << 1 << endl;
//    return 0;
//
//
//
//}





//#include<iostream>
//using namespace std;
//
//int main()
//{
//    //循环输入5个玩家的消费
//    //统计低于500的玩家数量
//
//    double money;
//    int player_cout = 0 ;
//    for(int  i = 0; i<5;i++)
//        cout << "请输入当前玩家的消费额:";
//        cin >> money;
//        //跳过500以上的情况
//        if(money >= 500)
//            continue;
//        player_cout ++;
//
//    cout << "消费低于500的玩家是 " << player_cout << endl;
//
//    return 0;
//}



////打印菱形
////本程序未完成
//#include <iostream>
//using namespace std;
//
//
//int main()
//{
//    //外层循环控制行(行数、换行)
//    //内层循环控制列(列数,列的图形)
//
//    for(int i = 0;i < 10; i++)
//    {
//        for(int j = 0; j<5;j++)
//        {
//            cout << "*" ;
//        }
//        cout << endl;
//    }
//}

数组 

//数组
#include <iostream>
#include<algorithm>

using namespace std;



//int main()
//{
//    int N = 100;    //变量 在c中不能赋值变量
//    int num[N];
//    num[0] = 9527;
//    cout << num[0] << endl;
//    return 0;
//}


////int array[] = {}   ///错误


////动态地从键盘录入信息并赋值(已完成)
////给数组赋值一个变量,并计算输入的数组元素的大小

//int main()
//{
//    int nums[1000000];
//    for(int i = 0; ; i++)
//    {
//
//        cout << "请输入第" << (i+1) << "个数组的元素:";
//        cin >> nums[i];
//    }
//
//
//
//    for(int i = 0; ; i++)
//    {
//
//        cout << nums[i] << endl;
//        cout << "输入的元素个数是:" << i << endl;
//    }
//
//    return 0;
//}


//
//int main()
//{
//    int nums[] = {8,4,2,1,23,344,12};
//    int nums_len = sizeof(nums) / sizeof(int);  //计算数组的长度
//    int sum =0;
//
//    for(int i = 0;i < nums_len;i++)
//    {
//        cout << nums[i] << '\t';
//    }
//    cout << endl;
//    //累加操作
//    for(int i = 0;i < nums_len;i++)
//    {
//        sum += nums[i];
//    }
//    cout << "数列的和为:" << sum << "\t平均值是" << sum / nums_len << endl;
//
//
////求数组的最大值和最小值
////假设第一个元素是最大值
//int max = nums[0];  //假设第一个元素是最大值
//int max_index = 0; //最大值的下标
//for(int i = 1; i < nums_len; i++)
//{
//
//    if(nums[i] > max)
//    {
//        max = nums[i];
//        max_index = i; //留下最大值的下表
//    }
//
//}
//cout << "最大值是:" << max << '\t' << nums[max_index] << endl;
//cout << "最大值的下标:" << max_index << endl;
//
//
////最小值同理
//
////求出奇数个数和偶数个数
//int ji_count = 0, ou_cout = 0;
//for(int i = 0; i < nums_len; i++)
//{
//    if(nums[i] % 2 ==0)
//    {
//        ou_cout++;   //一条语句时,大括号可以省略
//    }
//    else
//    {
//        ji_count++;
//    }
//
//}
//cout << "奇数个数是:" << ji_count << "\t 偶数个数是:" << ou_cout << endl;
//
//
//
//
//int search_num; //用户要查找的数字
//int search_index = -1; //用户查找数字的下标志
//cout << "请输入要查找的数字:" ;
//cin >> search_num;
////使用循环查找
//for(int i = 0; i < nums_len; i++)
//{
//    if(nums[i] == search_num)
//    {
//        search_index = i; //记录下查找到的元素的下标
//        break;
//    }
//}
//if(search_index == INT_MIN)
//{
//    cout << "数组中没有找到这个数字" << endl;
//}
//else
//{
//    cout << search_num << "在数组中的下标为:" << search_index <<endl;
//}
//}
//
//


//排序
//内层循环控制比较的次数
//内层循环控制每轮的比较和交换
//
////冒泡排序
////冒泡排序
//#include<iostream>
//using namespace std;
//int a[100];
//int main()
//{
//    int n;
//    cout << "请输入需要排序的数组的大小:";
//    cin >> n;  //确定数组的大小
//    for(int i = 0; i < n; i++)
//    {
//        cout << "请输入第" << i << "个元素的值" << endl;
//        cin >> a[i];   //输入数组各个元素的值
//    }
//
//    for(int i = 0; i < n - 1; i++) //如果有n个数,就要排序n-1次
//    {
//        for(int j = 0; j < n - 1 - i; j++) //执行每次排序的次数
//        {
//            if(a[j] > a[j + 1])  //如果这个数比后面那个大
//            {
//                swap(a[j],a[j+1]);  //将两个数互换位置
//            }
//        }
//    }
//    cout << "排序后的数组为:" << endl;
//    for(int i = 0;i < n; i++)
//    {
//        cout << a[i] << '\t';
//    }
//    return 0;
//}
//
//
//



//
//#include<iostream>
//using namespace std;
//
//
//int main()
//{
//    int a[100];  //初始化数组
//    int n;       //初始化数组元素个数变量
//    cout << "请输入要排序的数组元素的个数:" << endl;
//    cin >> n;
//
//    //给数组赋值
//    for(int i = 0; i < n; i++)
//    {
//        cout << "请输入第" << i + 1 <<"个元素的值" << endl;
//        cin >> a[i];
//    }
//
//    //外循环控制比较的轮数
//    //n - 1 次
//    for(int i = 0; i < n - 1; i++)
//    {
//        //内循环控制每轮的比较次数
//        //n - 1 - i
//        for(int j = 0; j < n - 1 - i;j++)   //越往后排序次数逐次减少,具体看动态图理解
//        {
//            if(a[j] > a[j+1])   //如果前边的数比后边的数大,就交换两个数的值
//            {
//                swap(a[j],a[j+1]);
//            }
//        }
//
//
//    }
//    cout << "排序后的数组是:" << endl;
//    for(int i = 0; i < n; i++)
//    {
//        cout << a[i] << '\t';   //输出排序后的数组
//    }
//}
//



//#include<iostream>
//using namespace std;
//
//int main()
//{
//    //选择排序
//    int nums[] {8,4,2,1,23,23,344,12};
//    //通过计算得到整形数组的实际长度(不能用于string数组)
//    int nums_len = sizeof(nums) / sizeof(int);
//    //“擂台”变量
//    int min = nums[0];  //假设最小值是数组的第一个元素
//    int min_index = 0;  //最小值的初始下标设置为0
//    int temp;
//    for(int i = 0; i < nums_len; i++)
//    {
//        min = nums[i];
//        min_index = i;
//        for(int j = i + 1;j < nums_len; j++)
//        {
//            if(nums[j] < min)
//            {
//                min = nums[j];
//                min_index = j;
//            }
//        }
//
//        //交换
//        if(min_index > i)  //可以不写
//        {
//            temp = nums[min_index];
//            nums[min_index] = nums[i];
//            nums[i] = temp;
//        }
//    }
//    cout << "排序后:" << endl;
//    for(int i = 0; i <nums_len;i++)
//    {
//        cout << nums[i] << endl;
//    }
//
//
//    //逆序
//    for(int i = 0; i < nums_len / 2; i++)
//    {
//        temp = nums[i];
//        nums[i] = nums[nums_len - i - 1];
//        nums[nums_len - i - 1] = temp;
//    }
//
//    cout << "逆序后:" << endl;
//    for(int i = 0; i <nums_len;i++)
//    {
//        cout << nums[i] << endl;
//    }
//
//}
//
//

//
//////描述:某游戏的战斗力排行系统,对给定的战斗力进行排行
//////并实现对排行的插入、删除等操作
//int main()
//{
//    //实现数组元素的删除和插入
//    double power[100];   //给数组预留空间
//    int power_cout = 0;  //当前数组中的元素的个数
//    double insert_power; //要插入的攻击力
//    int insert_index = 0;//默认插入到第一个元素位置
//
//    //////power = {1,2,3,4}; 不可以这样赋值,只能在声明时这样赋值
//    power[power_cout++] = 45771;
//    power[power_cout++] = 42322;
//    power[power_cout++] = 40907;
//    power[power_cout++] = 40706;
//
//
//    double temp;
//    for(int i = 0; i < power_cout; i++)
//    {
//        for(int j = 0; j < power_cout - i - 1; i++)
//        {
//            if(power[j] < power[j + 1])
//            {
//                temp = power[j];
//                power[j] = power[j+1];
//                power[j+1] = temp;
//            }
//        }
//    }
//    cout << "排序后:" << endl;
//    for(int i = 0;i < power_cout; i++)
//    {
//        cout << power[i] << '\t';
//    }
//
//    //插入方法一:放在数组末尾,然后重新排序
//    //插入方法二:1.找到第一个比插入数字大的位置insert_index
//    //           2.从最后一个元素开始,将数字复制到后面一个元素中
//    //           3.将要插入的数字赋值给下标为insert_index的元素
//
//    cout << "请输入要插入的数字:" << endl;
//    cin >> insert_power;
//    insert_index = power_cout;
//    //1.找到第一个比插入数字大的位置insert_index
//    for(int i = 0; i < power_cout; i++)
//    {
//        if(insert_power > power[i])
//        {
//            insert_index = i;
//            break;
//        }
//    }
//
//    //2.从最后一个元素开始,将数字复制到后面一个元素中
//    for(int i = power_cout - 1; i >= insert_index; i--)
//    {
//        power[i + 1] = power[i];
//    }
//
//
//    //3.将要插入的数字赋值给下标为insert_index的元素
//    power[insert_index] = insert_power;
//
//    //4.将数组的从长度+1
//    power_cout++;
//
//    cout << "插入后再排序:" << endl;
//    for(int i = 0;i < power_cout; i++)
//    {
//        cout << power[i] << '\t';
//    }
//
//
//    //删除
//    //1.找到要删除的元素下标
//    double delete_power;
//    int delete_index = INT_MIN;
//    cout << "请输入要删除的数字:";
//    cin >> delete_power;
//    for(int i = 0; i < power_cout; i++)
//    {
//        if(delete_power == power[i])
//        {
//            delete_index = i;
//            break;
//        }
//    }
//
//    if(delete_index == INT_MIN)
//    {
//        cout << "没有找到要删除的元素,删除失败!";
//    }
//
//    else
//    {
//        //2.从找到的下标开始,后边一个元素赋值给前边那个元素
//    for(int i = delete_index; i < power_cout - 1; i++)
//    {
//        power[i] = power[i + 1];
//    }
//    //3.总长度-1
//    power_cout--;
//    cout << "插入后:" << endl;
//    for(int i = 0; i < power_cout; i++)
//        {cout << power[i] << '\t';
//        }
//    }
//}





//////二维数组掌握的不是很好
//////仔细看看这个程序
//int main()
//{
//    //使用二维数组 "刘备","关羽","张飞"
//    string stu_names[] {"刘备","关羽","张飞"};
//    string course_names[] {"语文","数学","英语"};
//    const int ROW = 3;
//    const int COL = 3;
//    double scores[ROW][COL];
//    for(int i = 0;i < ROW; i++)
//    {
//        for(int j = 0; j < COL; j++)
//        {
//            cout << stu_names[i] << "的" << course_names[j] << "成绩" ;
//            cin >> scores[i][j];
//        }
//    }
//
//    cout << '\t';
//    for(int i = 0; i < COL;i++)
//    {
//        cout << course_names[i] << '\t';
//    }
//    cout << '\n';
//
//    for(int i = 0; i < ROW;i++)
//    {
//        cout << stu_names[i] << '\t';
//          for(int j = 0; j < COL;j++)
//        {
//            cout << scores[i][j] << '\t';
//        }
//    }
//    cout << endl;
//}



//数组的替代品vector (常用)
#include<vector>

int main()
{
    vector<double>vec_double = {98.5,67.9,43.6,32.9};
    //向数组中插入数字
    vec_double.push_back(100.8); //在数组的尾部插入一个数字
    //遍历
    for(int i = 0; i < vec_double.size(); i++)
    {
        cout << vec_double[i] << endl;
    }

//集合的通用遍历方法:使用迭代器 iterator
//以下是迭代器的基本使用方法(暂时超纲)
vector<double>::iterator it; //得到迭代器对象,实际上是一个指针对象
//从第一个元素开始迭代
//it.begin
//使用++it比it++效率要高
for(it = vec_double.begin(); it != vec_double.end();++it)
{
    cout << *it << endl;
}


//排序
//#include<algorithm>
sort(vec_double.begin(),vec_double.end());
for(it = vec_double.begin();it != vec_double.end(); ++it)
{
    cout << *it << endl;
}
}


////基本类型 int double float short 
////数组是不是一个类型?
////是的 int[]  double[]

 

指针

 

////指针

// #include <iostream>
// #include <cstdlib>

// using namespace std;

// int main()
// {
    // double num = 1024.5;
    // //声明一个指针,指向num变量
    // double* ptr_num = &num;
    // //*ptr_num = 1111;  //直接改变num的值,相当于num = 1111
    // cout << "ptr_num的值:" << ptr_num << '\t' << &num <<endl;
    // cout << "ptr_num指向的空间的值是:" << *ptr_num << endl;



    // char ch = 'a';
    // char * ptr_ch = &ch;
    // //思考:这里打印的结果是什么呢?
    // //我的答案:ch的地址(错)
    // cout << ptr_ch << '\t' << *ptr_ch << endl;
    // //这个地方有些特殊,char类型在C和C++会被当做字符串处理
    // cout << (void *)ptr_ch << endl;


    //空指针(null pointer)
    //空指针不指向任何对象,在试图使用一个指针之前可以首先检查是否为空
    // double * ptr_double;
    // cout << ptr_double << endl;
    //可以看出,不指定对象时,会有一个默认值
    //这种使用比较危险,野指针


    // //正确方法
    // double * ptr_double = nullptr;  //也可以使用NULL,需要cstdlib头文件
    // cout << ptr_double << endl;

//     return 0;
// }



// //void *指针
// #include <iostream>
// using namespace std;

// int main()
// {
//     double num = 3.14;
//     double * ptr_num1 = &num;
//     void * ptr_num2 = &num;
//     cout << boolalpha;  //布尔类型显示
//     cout << (ptr_num1 == ptr_num2) << endl;

//     *ptr_num2 = 112234;  //声明void类型是不可以操作,类型不清楚
//     return 0;
// }



// ////引用(reference)
// #include<iostream>
// using namespace std;

// int main()
// {
//     // int num = 1024;
//     // //错误用法int &ref_num = num;
//     // //引用必被初始化,它的底层其实也是指针
//     // cout << ref_num << endl;

//     //注意:
//     //1.引用并非对象,只是为了一个已经存在的对象起的别名
//     //2.引用只能绑定在对象上,不能与字面值或
//     //某个表达式的计算结果绑定在一起
//     //int &ref_value = 10; //错误
//     //const double &ref = 100; //正确
//     //3.引用必须初始化,所以使用引用之前不需要测试其有效性,
//     //因此使用引用可能会比使用指针效率高


//     //引用与指针的关系
//     //引用对指针进行了简单的封装,底层仍然是指针
//     //获取引用地址时,编译器会进行内部转换

//     // int num = 108;
//     // int & rel_num = num;
//     // rel_num = 118;
//     // cout << &num << '\t' << &rel_num << endl;
//     //cout << num << endl;
//     //上边的程序相当于
//     int num = 108;
//     int * rel_num = &num;
//     *rel_num = 118;
//     cout << &num << '\t' << rel_num << endl;
//     cout << num << endl;
// }



// //指针与数组
// #include <iostream>
// using namespace std;

// int main()
// {
//     double score[] = {11,22,33,44,55};
//     double * ptr_score = score;

//     cout << sizeof(score) << '\t' << sizeof(ptr_score) << endl;
//     cout << ptr_score[3] << endl;
//     cout << score << endl;  //首地址


//     cout << *(ptr_score + 31) << endl;

//     return 0;
// }


//动态分配内存
// #include<iostream>
// using namespace std;

// int main()
// {
//     //编译阶段分配内存int num[3];    int num1;
//     //运行阶段分配空间  堆区
//     int * ptr_int = new int;
//     //成对出现,释放内存
//     delete ptr_int;

//     //编译时  --  包办婚姻
//     ////int nums[56];
//     //运行时  --  用多少,new多少
//     ////int * num[56] = new int[56]
//     int num[5];
//     int * nums = new int[5];
//     cout << sizeof(num) << '\t' << sizeof(nums) << endl;

// }


// #include<iostream>
// using namespace std;

// int main()
// {
//     int *ptr = new int;
//     *ptr = 90;

//     int *ptr1 = ptr;
//     delete ptr;
//     cout << *ptr << endl;
// }


////释放new创建的数组要加[]
////int * ptr_int = new int;
////short * ptr_short = new short[5];
////delete ptr_int;
////delete [] ptr_short;


// ///////////////////////////////
// ////内存的分配位置
// #include <iostream>
// using namespace std;


// int num1 = 0; //全局初始化区
// i那天* ptr1;  //全局未初始化区
// int main()
// {
//     //栈区
//     int num2;
//     //栈区
//     char str[] = "Hello";
//     //栈区
//     char * ptr2;
//     //Hello以及\0在常量区,ptr3在栈区
//     char * ptr3 = "Hello";
//     //全局(静态)初始化区
//     static int num3 = 1024;
//     //分配的内存在堆区
//     ptr1 = new int[10];
//     ptr2 = new char[20];
//     //注意:ptr1和ptr2本身实在栈中的
//     return 0;
// }


// ////使用指针访问数组
// #include <iostream>
// using namespace std;

// int main()
// {
//     int arrays[] = {15,23,30,40,50};
//     int * p_arrays = arrays;

//     for(int i = 0; i < 5; i++)
//     {
//         cout << *(p_arrays + i) << endl;
//     }
// }


// ////使用指针实现逆序
// ////如果再增加一个元素的话,程序会报错,待解决
////提示:start < end
// #include<iostream>
// using namespace std;

// int main()
// {
//     int arrays[] = {15,23,30,40,50};
//     int * ptr_start = arrays;  //指向第一个元素
//     int * ptr_end   = arrays + 4;   //指向最后一个元素
//     int temp;

//     while(ptr_start != ptr_end)
//     {
//         temp = *ptr_start;
//         *ptr_start = *ptr_end;
//         *ptr_end   = temp;
//         ptr_start++;
//         ptr_end--;
//     }
//     for(int i = 0;i < 5; i++)
//     {
//         cout << arrays[i] << endl;
//      }

// }



// ////二维数组
// ////不是很理解
// #include<iostream>
// using namespace std;

// int main()
// {
//     int *p = new int[10];
//     //使用指针创建二维数组
//     int arrays[5][3] =
//     {
//         {1,2,3},
//         {4,5,6},
//         {7,8,9},
//         {10,11,12},
//         {13,14,15}
//     };

//     int (*p2)[3] = arrays;
//     for(int i = 0; i < 5; i++)
//     {
//         for(int j = 0; j < 3; j++)
//         {
//             cout << *(*(p2+i) + j) << ',';
//         }
//         cout << endl;
//     }
//     cout << &arrays[1][0] << endl;
//     for(int i = 0; i < 5; i++)
//     {
//         cout << p2 + i << endl;
//     }
// }



////
//#include<iostream>
//using namespace std;
//
//int main()
//{
//    int num[10];
//    int *p_num = num;
//    int (*p)[4] = new int[4][4];
//    cout << sizeof(num) << endl;
//    cout << sizeof(p_num) << endl;
//    cout << sizeof(p) << endl;
//    return 0;
//}

 实战训练:小公主养成记

函数

////函数

//C++不允许返回单独数组类型,可以放在结构中返回
//使用函数计算两数之和
#include <iostream>
using namespace std;

int sum(int,int);  //函数原型


int main()
{
    int result;
    result = sum(10,20); //调用函数
    cout << result << endl;

    return 0;
}


int sum(int x,int y)
{
    int z;
    z = x +y;
    return z;
}



//使用函数计算体积 长方体、圆柱体、圆锥体
#include <iostream>
#include <cmath>
using namespace std;


void calcCuboid(); //计算长方体体积
void calcCylinder();  //计算圆柱体体积

int main()
{
    int choice = -1;
    while(choice)
    {
        cout << "1.长方体" << endl;
        cout << "2.圆柱体" << endl;
        cout << "0.退出" << endl;
        cin >> choice;
        switch(choice)
            {
            case 1:
                calcCuboid();
                break;
            case 2:
                calcCylinder();
                break;
            case 0:
                break;
            }
    }

    cout << "感谢使用";
    return 0;
}

void calcCuboid()
{
    double len, width,height;
    cout << "请输入长宽高:" << endl;
    cin >> len >> width >> height;
    double v = len * width * height;
    cout << "长方体的体积:" << v << endl;
}

void calcCylinder()
{
    double radius,height;
    cout << "请输入半径和高:" << endl;
    cin >> radius >> height;
    double pi = 4 * atan(1.0); //圆周率公式
    double v = pi * pow(radius,2) * height;
    cout << "圆柱体的体积是:" << v << endl;

}



//升级小公主
//头文件 GzDemo.h
#ifndef GZDEMO_H_INCLUDED
#define GZDEMO_H_INCLUDED
//升级小公主
#include <iostream>
using namespace std;
//函数定义
//基本属性的录入和排序功能

void input(int [],int);
void print(int [],int);



//函数实现
void input(int values[10], int len) //数组的长度
{
    if(len >5)
    {
        cout << "数组长度只能是5以内!" << endl;
        return ;  //退出返回值为void的函数
    }

    string valueNames[] = {"体力","智力","魅力","道德","气质"};
    for(int i = 0; i < len; i++)
    {
        cout << valueNames[i] << ":";
        cin >> values[i];

    }


}


void print(int values[], int len)
{
    string valueNames[] = {"体力","智力","魅力","道德","气质"};
    for(int i = 0; i < len; i++)
    {
        cout << valueNames[i] << ":" << values[i] << endl;
    }
}
#endif // GZDEMO_H_INCLUDED


//主函数
#include <iostream>
#include "GzDemo.h"
using namespace std;


int main()
{
    int values[5];
    input(values,5);
    print(values,5);
}



#include <iostream>
using namespace std;

void show(int [], int);

int main()
{

    int valueArray[] = {90,56,67,89,100};
    show(valueArray,5);
    show(valueArray,5);
}

void show(int valueArray[], int len)
{
    for(int i = 0; i < len; i++)
    {
        cout << valueArray[i]++ << '\t';
    }
    cout << endl;
}
//可以发现,两次调用会导致数组的值会被修改
//解决方案是,使用const关键字
//void show(const int valarray[], int len)
//void show(const int * valarray, int len)
//二维数组的传参
//还有些问题,待排查
//头文件

#ifndef DEMO_H_INCLUDED
#define DEMO_H_INCLUDED
//二维数组的传参
#include<iostream>
using namespace std;

void show(double (*)[5], int );

void show(double (*arrs)[5],int len)
{
    for(int i = 0; i < len; i++)
    {
        for(int j = 0; j < 5; j++)
        {
            cout << arrs[i][j] << '\t';
        }
    }
}


#endif // DEMO_H_INCLUDED


//主函数
#include<iostream>
#include"demo.h"
using namespace std;

int main()
{
    double powers[3][5] =
    {
        {11,22,33,44,55},
        {66,77,88,99,01},
        {02,03,04,05,06},
    };
   show(powers,3);
}
////函数指针
////函数原型:
////double sum(double,double);
////函数指针声明:
////double (*ptrSum)(double,double)

//头文件
#ifndef DEMO_H_INCLUDED
#define DEMO_H_INCLUDED

#include<iostream>
using namespace std;

int power(int,int);

int power(int num1, int num2)
{
    int  result = 1;
    for(int i = 0; i < num2; i ++)
    {
        result *= num1;
    }
    return result;
}

#endif // DEMO_H_INCLUDED


//主函数
#include <iostream>
#include "demo.h"
using namespace std;

int main()
{
    //声明函数指针
    int (*ptrPower)(int, int);
    //让声明的函数指针指向函数,以便调用
    ptrPower = power;
    cout << (*ptrPower)(2,10) << endl;
    //cout << ptrPower(2,10) << endl;
    //cout << power(2,10) << endl;
}
////自定义计算器(使用函数指针)函数指针还不是很理解,有待研究
////头文件
#ifndef DEMO_H_INCLUDED
#define DEMO_H_INCLUDED

#include<iostream>
using namespace std;

///加法
double addition(double, double);
///减法
double subtraction(double, double);
///乘法
double multiplication(double, double);
///除法
double division(double, double);
// 打印计算结果
void print_result(double (*)(double,double),double,double);
void print_result(double (*ptrCalc)(double,double),double num1,double num2)
{
    //调用函数,打印函数
    double result = ptrCalc(num1,num2);
    cout << "运算结果为:" << result << endl;
}
double addition(double num1, double num2)
{
    return num1 + num2;
}

double subtraction(double num1, double num2)
{
    return num1 - num2;
}

double multiplication(double num1, double num2)
{
    return num1 * num2;
}

double division(double num1, double num2)
{
    if(num2 == 0)
    {
        cout << "除数不能为0" << endl;
        return 0;
    }

    return num1 / num2;
}

#endif // DEMO_H_INCLUDED


////主函数
#include <iostream>
using namespace std;
#include "demo.h"
int main()
{
    //定义函数指针
    double (*ptrCalc)(double,double);
    double num1,num2;
    char op;
    cout << "请输入两个操作数:" ;
    cin >> num1 >> num2;
    cout << "请输入运算符:";
    cin >> op;
    switch(op)
    {
        case '+':
            ptrCalc = addition;
            break;
        case '-':
            ptrCalc = subtraction;
            break;
        case '*':
            ptrCalc = multiplication;
            break;
        case '/':
            ptrCalc = division;
            break;
    }
    print_result(ptrCalc,num1,num2);

}

 内联函数

是C++为提高程序运行速度所做的一项改进,普通函数在被主函数调用时会根据函数地址去寻找函数并执行函数的内容,而内联函数则直接将函数复制过来执行。相当于在书中的注释,可以节省“查字典”的时间。使用方法是直接在声明或者定义时,在函数前边加inline。(有时候编译器会选择性的忽略·····等于没写,哈哈哈)

使用建议:代码执行时间较短时,内联函数就可以节省大部分时间,但是如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程的很小一部分,不建议使用内联函数。同时它的代价是,占用内存,尤其是在多个函数、多次调用的时候。

#include <iostream>
using namespace std;
//内联的初级版本就是C中的宏定义替换
//#define N 5 //c语言中的宏定义替换
//#define S(num) num * num  //宏定义了一个S(num)函数
////以后在所有使用S(num)的地方,就自动替换成num * num

inline int S(int);

int main()
{
    int result1 = S(5 + 10);  //会发生错误:5 + 10 * 5 + 10 = 65
    double result2 = S(2.5);
    cout << result1 << endl;
    cout << result2 << endl;
    return 0;
}

int S(int num)
{
    return num * num;
}
//////引用回顾
//double& d = 12.3;
//d = 111;   //违背了常量的基本概念
//////指向常量的引用——合法的
//const double& d = 12.3;
//////我们在引用的时候,不需要测试其有效性
//////所以我们使用引用比指针的效率要高
//



#include <iostream>
using namespace std;

void swap1(int, int);
void swap2(int*, int*);
void swap3(int&, int&);
void show(const int&, const int&);

int main()
{
    int num1 = 10, num2 = 5;
    swap1(num1, num2);
    //cout << num1 << '\t' << num2 << endl;
    show(num1,num2);
    swap2(&num1, &num2);
    cout << num1 << '\t' << num2 << endl;
    swap3(num1, num2);
    cout << num1 << '\t' << num2 << endl;
    return 0;
}

void swap1(int num1, int num2)
{

    int temp;
    temp = num1;
    num1 = num2;
    num2 = temp;
}
void swap2(int * p1, int * p2)
{
    int temp;
    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
void swap3(int & ref1, int & ref2)
{
    //使用引用的理由
    //1.可以更加简便的书写代码
    //2.可以直接传递某个对象,而不只是把对象赋值一份
    //3.
    int temp;
    temp = ref1;
    ref1 = ref2;
    ref2 = temp;

}
void show(const int& num1, const int& num2)
{
    //我们希望显示函数中,只能实现传入参数的显示功能
    //而禁止显示函数修改num1和num2的值(禁止函数内部修改引用参数值)
    //解决方案:在参数中使用const
    cout << num1 << '\t' << num2 << endl;
}
////函数返回引用类型
#include <iostream>
using namespace std;

int& sum() //返回引用类型的函数
{
    int num = 10;
    //注意:rNum是在sum函数中定义的,所以叫它局部变量
    //rNum的生存期只在sum()函数中;
    int& rNum = num;
    //函数中的内部变量会被内存回收
    //所谓的内存回收,并不是把内存保存的设置清零
    //而是指内存中你的程序申请的这块内存已经不是你的了!
    //不要返回局部变量的引用!!
    //有时候不会回收,有时候会返回另外一个分配的值
    
    return rNum; //返回了一个局部的引用类型变量

}

void test()
{
    int x = 1;
    int y = 2;
    int z = 1024;
    //test中定义的变量有可能会占用上边函数栈上的数据
}
int main()
{
    int result = sum();
    test();
    cout << "result = " << result << endl;
}
//函数可以不返回值,默认返回传入的引用对象本身
#include <iostream>
using namespace std;

int& sum(int& num1, int& num2)
{
    num1++;
    num2++;
    //默认返回最后一个引用num2++
    ////return num1 + num2;  //会出错
    //只能返回num1 或者 num2
}

int main()
{
    int num1 = 10, num2 = 15;
    int& result = sum(num1, num2);
    cout << "result =" << result << endl;
    return 0;
}
//函数可以不返回值,默认返回传入的引用对象本身
#include <iostream>
using namespace std;

int& sum(int& num)
{
  num++;
  return num;
}

int main()
{
    int num = 10;
    int& result = sum(num);
    sum(num) = 55;  //会给result直接赋值
    cout << "result =" << result << endl;
    return 0;
}
////解决方案:
////1.将返回类型修改为const int&
////const int &sum(int& num){...}
////2.const类型为不可修改的左值,sum(num) = 55将不合法
////3.省略const会使函数的含义等价模糊,建议避免在设计函数中
////存在模糊的情况,因为模糊的情况会增加犯错误的机会,应尽量避免错误
////模拟实现游戏中的私聊函数
/**
 *跟某人聊天 -- 负责字符串的拼接(聊天格式)
 *@param toName 聊天对象的名称
 *@param content 聊天对象的内容
 *@return 按某规定的格式拼接聊天信息后的字符串
*/

#include <iostream>
using namespace std;

string chatTo(const string& toName, const string& content);  //使用const不会修改聊天内容
string chatFrom(const string& fromName, const string& content);

int main()
{
    string toName,content,chatMsg;
    cout <<"请输入对方的名称:";
    getline(cin,toName);
    cout << "请输入发送给对方的聊天信息的:";
    getline(cin,content);
    chatMsg = chatTo(toName,content);
    cout << endl << chatMsg << endl;
}

string chatTo(const string& toName, const string& content)
{
    string msg = "※ 你悄悄地对 [" + toName + "] 说:" + content;
    return msg;
}

string chatFrom(const string& fromName, const string& content)
{
///////////////接收信息,自行实现
}
////默认参数
////void sample(int 10);
////注意:1.默认值可以在函数原型或定义中给出,不能在这两个位置同时出现
////2.对于带参数列表的函数,必须从右向左添加默认值
////void test1(int a, int b, int c = 10); 正确
////void test2(int a, int b, int c); 错误
////void test3(int a = 1, int b = 5, int c = 10); 正确
////函数重载
////编译器在编译时,根据参数列表对函数进行重命名
void Swap(int a, int b)
//编译器中:Swap_int_int
void Swap(float a, float b)
//编译器中:Swap_float_float

//重载决议

string food = "佛跳墙";
string &rfoof = foof;
eating(food);
eating(rfoof);
//运行后会出现error: call of overloaded 'eating(std::string&)' is ambigious!
//注意:
//1.从编译器角度看,eating(string) 和eating(string&)的特征标是相同的
//调用时都可以写作:eating(food);
//为了避免混乱,编译器把类型引用和类型本身视为同一个特征标
//2.调用匹配函数时,不区分const和非const变量
////使用重载实现数组的排序
#include <iostream>
using namespace std;
//函数名相同,参数列表(特征标不同)
void Sort(int[],int len); //数组默认传入的是地址,传长度可以省去计算长度当地麻烦
void Sort(float[],int len);
void Sort(double[],int len);

void Show(int[],int len);
void Show(float[],int len);
void Show(double[],int len);


int main()
{
    int iNums[] = {56,54,12,89,43};
    float fNums[] = {78.0f,5.7f,42.8f,99.1f};
    double dNums[] = {78.9,23.6,77.8,98.5,33.3};
    cout << "排序前:" << endl;
    Show(iNums, sizeof(iNums) / sizeof(iNums[0]));
    Show(fNums, sizeof(fNums) / sizeof(fNums[0]));
    Show(dNums, sizeof(dNums) / sizeof(dNums[0]));

    //排序
    Sort(iNums, sizeof(iNums) / sizeof(int));
    Sort(fNums, sizeof(fNums) / sizeof(float));
    Sort(dNums, sizeof(dNums) / sizeof(double));

    cout << "排序后:" << endl;
    Show(iNums, sizeof(iNums) / sizeof(iNums[0]));
    Show(fNums, sizeof(fNums) / sizeof(fNums[0]));
    Show(dNums, sizeof(dNums) / sizeof(dNums[0]));
}

////参数是数组时,会自送降为指针!
//排序函数
void Sort(int nums[],int len)
{
    int temp;
    //cout << "sizeof(nums) = " << sizeof(nums) << endl;
    for(int i = 0; i < len; i++)
        for(int j = 0; j < len - i - 1; j++)
        {
            if(nums[j] > nums[j + 1])
            {
                temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
            }

        }

}


void Sort(float nums[],int len)
{
    int temp;
    for(int i = 0; i < len; i++)
        for(int j = 0; j < len - i - 1; j++)
        {
            if(nums[j] > nums[j + 1])
            {
                temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
            }

        }

}

void Sort(double nums[],int len)
{
    int temp;
    for(int i = 0; i < len; i++)
        for(int j = 0; j < len - i - 1; j++)
        {
            if(nums[j] > nums[j + 1])
            {
                temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
            }

        }

}


//显示函数
void Show(int nums[],int len)
{
    for(int i = 0; i < len; i++)
    {
        cout << nums[i] << '\t';
    }
    cout << endl;
}
void Show(float nums[],int len)
{
    for(int i = 0; i < len; i++)
    {
        cout << nums[i] << '\t';
    }
    cout << endl;
}
void Show(double nums[],int len)
{
    for(int i = 0; i < len; i++)
    {
        cout << nums[i] << '\t';
    }
    cout << endl;
}

 可以看出定义函数时,非常麻烦,可以采用模板函数来解决(尝试编写代码简化上述代码):

////函数模板
////所谓函数模板,实际上就是建立一个通用函数
////1.函数定义时不指定具体类型(使用虚拟类型代替)
////2.函数被调用时编译器根据实参反推数据类型-类型的参数化
////template <typename 类型参数1 , typename 参数类型2 ...>
template<typename T>
void Swap(T &a, &b)
{
    T temp = a;
    a = b;
    b = temp; 
}

但是函数模板并不能全部代替函数重载,函数重载也有本身的优势。

构造函数(代码不完全,需要重新学习,课时95)

////四个头文件

////LandOwner.hpp
#ifndef LANDOWNER_H
#define LANDOWNER_H

#include <iostream>
using namespace std;

////.hpp文件一般包含实现的内联函数
////通常用于模板类这种声明与实现共存的情况
////建议:只要不是纯模板,一律使用.h作为头文件后缀
////使用.cpp作为函数的实现文件

class LandOwner
{

    private:
        string name;  //地主的名字
        long score;  //地主的积分
        int cards[20];  //地主的手牌


    public:
        LandOwner() {}  //实现了默认构造函数
        virtual ~LandOwner() {}
         inline void TouchCard(int cardCount) //默认有inline,可以不写
         {
             //暂时省略函数的实现
             cout << name << "摸了" << cardCount << "张牌" << endl;
         }

         void ShowScore()
         {
             cout << name << "当前积分为:" << score << endl;
         }

    protected:


};

#endif // LANDOWNER_H



////LandOwnerV2.h
#ifndef LANDOWNERV2_H
#define LANDOWNERV2_H

#include <iostream>
using namespace std;

class LandOwnerV2
{
    //private:
      public:
        string name;  //地主的名字
        long score;  //地主的积分
        int cards[20];  //地主的手牌

    public:
        LandOwnerV2();  //构造函数的声明
        virtual ~LandOwnerV2();  //析构函数的声明

        void TouchCard(int cardCount);  //声明摸牌方法
        void ShowScore();  //声明的显示积分的方法

    protected:


};

#endif // LANDOWNERV2_H



////LandOwnerV3.h
#ifndef LANDOWNERV3_H
#define LANDOWNERV3_H
////用来演示封装的基本概念
////程序有错,待排查
#include <iostream>
using namespace std;

class LandOwnerV3
{
    //省略了private
    //解决积分被修改为负数错误的方法:
    //将成员变量score进行隐藏并封装
    long score;
    int cards[20];  //地主的手牌
    string name;  //地主的名字

    public:

        LandOwnerV3();
        virtual ~LandOwnerV3();

        void ShowScore();

        //使用方法(函数)来实现对成员变量的封装 Get和Set方法
        void SetScore(long lscore)  //lscore尽量和score命名不一样
        {
            if(lscore < 0)
            {
                //如果传入的积分是非法情况,那么积分默认为0
                score = 0;
            }
            else
            {
            //积分为正数时,才进行赋值操作
            //这里就通过条件判断,封装了score的赋值过程
            score = lscore;
            }

};

#endif // LANDOWNERV3_H



//// LandOwnerV4.h
#ifndef LANDOWNERV4_H
#define LANDOWNERV4_H

////使用工具自动生成Get和Set方法,演示构造函数

#include <iostream>
using namespace std;

class LandOwnerV4
{
    public:
        LandOwnerV4();
        virtual ~LandOwnerV4();

        long Getscore() { return score; }

        void Setscore(long val)
        {
            if(val < 0) _score = 0;
                        _score = val;
        }

        string Getname() { return name; }

        void Setname(string val) { name = val; }

       // int Getcards[20]() { return cards[20]; }

       // void Setcards[20](int val) { cards[20] = val; }


    protected:

    private:
        long _score;
        string name;
        int cards[20];


#endif // LANDOWNERV4_H



////主函数
////面向对象

#include <iostream>
//#include "LandOwner.hpp"  //如果要使用类,必须包含类的头文件
//#include "LandOwnerV2.h"
//#include "LandOwnerV3.h"
#include "LandOwnerV4.h"
using namespace std;

int main()
{
    /////////////LandOwner

//    //普通的类型: 数据类型  变量   int num;
//    LandOwner LandOwner1;  //声明了一个LandOwner1类型的变量 地主一号
//    //调用对象的成员方法
//    //LandOwner1.cards[0] = 9;  //不能直接使用对象的私有成员
//    LandOwner1.TouchCard(100);
//    return 0;


//    /////////////LandOwnerV2
//    LandOwnerV2 LandOwner2;  //地主2号变量
//    LandOwner2.name = "于谦";
//    LandOwner2.TouchCard(20);
//    return 0;


//      /////////////LandOwnerV3
//      LandOwnerV3 LandOwner3;
//      LandOwner3.name = "巴依老爷";
//      //注意:为地主修改积分
//      LandOwner3.SetScore(-10);
//      LandOwner3.ShowScore();
//      return 0;


//      /////////////LandOwnerV4
        LandOwnerV4 LandOwner4;


}

 带参构造函数

 

////Student.h
#ifndef STUDENT_H
#define STUDENT_H

#include <iostream>
using namespace std;
class Student
{
    public:
        //构造函数的重载规则与普通函数重载相同
        Student();
        Student(int);
        //Student(string);
        Student(string, string);  //带参构造
        ~Student();

        void ShowInfo();

        string GetName() { return m_Name; }
        void SetName(string val) { m_Name = val; }
        string Getdesc() { return m_desc; }
        void Setdesc(string val) { m_desc = val; }
        int Getage() { return m_age; }
        void Setage(int val)
        {
            if(val < 0)
            {
                m_age = 18;
            }
            else
            {
                m_age = val;
            }
        }

    protected:

    private:
        string m_Name;
        string m_desc;
        int m_age;
};

#endif // STUDENT_H


////Student.cpp
#include "Student.h"

Student::Student()
{
    cout << "默认构造" << endl;
}

//Student::Student(strintg name)
//{
//    Student(name);
//    cout << "调用带参构造:Student::Student(strintg name)" << endl;
//
//}

Student::Student(int age)
{
    Setage(age);
    cout << "调用带参构造:Student::Student(int age)" << endl;
}

//初始化参数列表的写法
Student::Student(string name, string desc) : m_Name(name), m_desc(desc)
//Student::Student(string name, string desc)
{
//    SetName(name);  //等价写法m_Name = name;
//    m_desc = desc;
    cout << "调用带参构造:Student::Student(string name, string desc))" << endl;
}

void Student::ShowInfo()
{
    cout << m_desc << m_Name << endl;
}
Student::~Student()
{
    cout << m_Name << "被释放" << endl; //杰克马没有被释放,需要用delete释放内存
}


////main.cpp
#include <iostream>
#include "Student.h"
using namespace std;

int main()
{
    Student stu1;  //在栈内存中直接分配空间
    Student stu2("马化腾","普通家庭");
//    Student stu3(45);
//    Student stu4 = 50;
    stu2.ShowInfo();
    Student* stu5 = new Student("杰克马","悔创阿里");
    stu5->ShowInfo();
  delete stu5;  //释放杰克马
return 0; }

析构函数
1.对象过期时自动调用的特殊成员函数
2.析构函数一般用来完成清理工作
3.析构函数的名称是在类名前加上~
4.析构函数没有参数,只能有一个

注意:
1.析构函数用来释放对象使用的资源,并销毁对象的非static静态数据成员
2.无论何时一个对象被销毁,都会自动调用析构函数(隐式析构)

 

////斗地主地主类基本信息程序


////LandOwner.h

#ifndef LANDOWNER_H
#define LANDOWNER_H
#include <iostream>
using namespace std;

class LandOwner
{
    public:
        LandOwner();
        LandOwner(string);
        LandOwner(string,string,int,long);
        ~LandOwner();

        string GetNickName() { return m_NickName; }
        void SetNickName(string val) { m_NickName = val; }
        string GetSex() { return m_Sex; }
        void SetSex(string val) { m_Sex = val; }
        int GetGold() { return m_Gold; }
        void SetGold(int val) { m_Gold = val; }
        long GetExp() { return m_Exp; }
        void SetExp(long val) { m_Exp = val; }


        void ShowInfo();

    protected:

    private:
        string m_NickName;
        string m_Sex;
        int m_Gold;
        long m_Exp;
};

#endif // LANDOWNER_H



////LandOwner.cpp
#include "LandOwner.h"

LandOwner::LandOwner()
{
    SetNickName("默认地主");
    SetSex("保密");
    SetExp(0);
    SetGold(1000);
    cout << "调用了LandOwner()" << endl;
}

LandOwner::LandOwner(string nickName): m_NickName(nickName)
{
    SetSex("保密");
    SetExp(0);
    SetGold(1000);
    cout << "调用了LandOwner(string nickName)" << endl;
}

LandOwner::LandOwner(string nickName, string sex, int gold, long exp):m_NickName(nickName),m_Sex(sex),m_Gold(gold),m_Exp(exp)
{
    cout << "调用了LandOwner(string nickName, string sex, int gold, long exp)" << endl;
}

void LandOwner::ShowInfo()
{
    cout << "昵称:" << GetNickName() << endl;
    cout << "性别:" << GetSex() << endl;
    cout << "昵称:" << GetGold() << endl;
    cout << "经验:" << GetExp() << endl;
}
LandOwner::~LandOwner()
{
    cout << GetNickName() << "被释放!" << endl;
}




////main.cpp
#include <iostream>
#include "LandOwner.h"
using namespace std;

int main()
{
    LandOwner* ptr_landOwner1 = new LandOwner();
    LandOwner* ptr_landOwner2 = new LandOwner("专业斗地主");
    LandOwner* ptr_landOwner3 = new LandOwner("周扒皮");

    ptr_landOwner1->ShowInfo();
    ptr_landOwner2->ShowInfo();
    ptr_landOwner3->ShowInfo();

    delete ptr_landOwner1;
    delete ptr_landOwner2;
    delete ptr_landOwner3;
    return 0;
}

添加抽牌功能:

////LandOwner.h////
#ifndef LANDOWNER_H
#define LANDOWNER_H
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;

class LandOwner
{
    private:
        string m_NickName;
        string m_Sex;
        int m_Gold;
        long m_Exp;
        vector<int> packCards; //默认的一副牌,从1-54
        vector<int> surplusCards; //摸牌后,剩余的牌
        vector<int> currCards; //当前玩家的手牌组数
        bool isContains(int); //剩余牌集合中是否包含cardNum这个牌面
        void deleteCard(vector<int>&, int);  //删除集合中的数字
        string getColor(int); //获得牌的花色
        string getValue(int);  //获得牌面

    public:
        LandOwner();
        LandOwner(string);
        LandOwner(string,string,int,long);
        ~LandOwner();

        string GetNickName() { return m_NickName; }
        void SetNickName(string val) { m_NickName = val; }
        string GetSex() { return m_Sex; }
        void SetSex(string val) { m_Sex = val; }
        int GetGold() { return m_Gold; }
        void SetGold(int val) { m_Gold = val; }
        long GetExp() { return m_Exp; }
        void SetExp(long val) { m_Exp = val; }

        void TouchCard(int); //摸牌
        void ShowInfo();
        void InitCards();  //初始化packCard,surplusCards,currCards
        void ShowCards(const vector<int>&);  //显示集合中的牌面

    protected:


};

#endif // LANDOWNER_H



////LandOwner.cpp////
#include "LandOwner.h"

LandOwner::LandOwner()
{
    SetNickName("默认地主");
    SetSex("保密");
    SetExp(0);
    SetGold(1000);
    cout << "调用了LandOwner()" << endl;
    InitCards();
}

LandOwner::LandOwner(string nickName): m_NickName(nickName)
{
    SetSex("保密");
    SetExp(0);
    SetGold(1000);
    cout << "调用了LandOwner(string nickName)" << endl;
    InitCards();
    //测试isContains
    cout << " 测试isContains:" << isContains(13) << endl;
}

LandOwner::LandOwner(string nickName, string sex, int gold, long exp):m_NickName(nickName),m_Sex(sex),m_Gold(gold),m_Exp(exp)
{
    cout << "调用了LandOwner(string nickName, string sex, int gold, long exp)" << endl;
}

void LandOwner::ShowInfo()
{
    cout << "昵称:" << GetNickName() << endl;
    cout << "性别:" << GetSex() << endl;
    cout << "昵称:" << GetGold() << endl;
    cout << "经验:" << GetExp() << endl;
}

void LandOwner::InitCards()  //初始化packCard,surplusCards,currCards
{
    //生成默认的一副扑克牌
    for(int i = 0; i < 54; i++)
    {
        packCards.push_back(i + 1);
        surplusCards.push_back(packCards.at(i));
    }
    currCards.clear();
}

void LandOwner::ShowCards(const vector<int>& cards)
{
//    //C语言的习惯
//    for(int i = 0; i < cards.size(); i++)
//    {
//        cout << cards[i] << ",";
//    }
//    cout << endl;

//       //使用迭代器
//       for(vector<int>::const_iterator iter = cards.begin(); iter != cards.end();iter++)
//       {
//           cout << *iter << "," ;
//       }
//       cout << endl;

         //使用C++11的类型推断
//         for(auto iter = cards.begin(); iter != cards.end();iter++)
//       {
//           cout << *iter << "," ;
//       }
//       cout << endl;

//         //for区间遍历 - C++11
         for(auto card : cards)
         {
             cout << card << ":"<< getColor(card) << "-" << getValue(card) << ",";
             //cout << getColor(card) << "-" << getValue(card) << ",";
         }
         cout << endl;

            //使用算法的方式,将容器的内容复制到cout绑定的迭代器中
            //#include<iterator>
            //#include<algorithm>
            //copy(cards.cbegin(),cards.end(),ostream_iterator<int>(cout,","));
            //cout << endl;
}

void LandOwner::TouchCard(int cardCount)
{
    //随机生成一张剩余牌集合中有的牌
    //添加到currCards集合中,从surplusCards中删除这张牌
    srand(time(NULL));  //时间种子
    for(int i = 0; i < cardCount; i++)
    {
        int randIndex = rand() % 54;  //0——53之间的随机数字
        //判断:随机生成的这张牌是否在剩余牌集合中
        if(isContains(packCards[randIndex]))
        {
            //将摸的牌放入当前手牌数组
            currCards.push_back(packCards[randIndex]);
            //在剩余牌集合中删除这张牌
            deleteCard(surplusCards, packCards[randIndex]);
        }
        else
        {
            i--;  //重新摸牌
        }
    }
    cout << "<地主摸牌> -- 当前手牌如下:" << endl;
    ShowCards(currCards);
    cout << "<地主摸牌后> -- 剩余牌面如下:" << endl;
    ShowCards(surplusCards);

}

bool LandOwner::isContains(int cardNum)
{
    //使用算法查找
    vector<int>::iterator iter = find(surplusCards.begin(),surplusCards.end(),cardNum);
////    if(iter == surplusCards.end())
////    {
////        return false;
////    }
////    return true;
    return iter != surplusCards.end();

//    //普通青年的做法
//    for(int i = 0; i < surplusCards.size(); i++)
//    {
//        if(surplusCardsp[i] == cardNum)
//        {
//            return true;
//        }
//    }
//    return false;
}


void LandOwner::deleteCard(vector<int>& cardVec, int card)
{
    //普通青年的做法
//    for(auto iter = cardVec.begin(); iter != cardVec.end();)
//    {
//        if(*iter == card)
//        {
//            //如果找到就删除元素
//            iter = cardVec.erase(card);//这里的返回值指向已删除元素的下一元素
//        }
//        else
//        {
//            ++iter; //继续判断下一个元素是否相同
//        }
//    }

        //使用算法删除
        auto iter = find(cardVec.begin(),cardVec.end(), card);
        if(iter != cardVec.end())
        {
            cardVec.erase(iter);
        }
}

string LandOwner::getColor(int card)
{
    if(card == 53) return "小王";
    if(card == 54) return "大王";
    string colors[] = {"黑桃","红心","方块","梅花"};
    return colors[(card - 1) / 13];
}

string LandOwner::getValue(int card)
{
    if(card == 53) return "Black Joker";
    if(card == 54) return "Red Joker";
    string values[] = {"A","1","2","3","4","5","6","7","8","9","10","J","Q","K"};
    return values[(card - 1) % 13];
}
LandOwner::~LandOwner()
{
    cout << GetNickName() << "被释放!" << endl;
}



////main.cpp////
#include <iostream>
#include "LandOwner.h"
using namespace std;

int main()
{
    LandOwner* ptr_landOwner1 = new LandOwner();
    LandOwner* ptr_landOwner2 = new LandOwner("专业斗地主");
    LandOwner* ptr_landOwner3 = new LandOwner("周扒皮");

    ptr_landOwner1->ShowInfo();
    ptr_landOwner2->ShowInfo();
    ptr_landOwner3->ShowInfo();

    ptr_landOwner2->TouchCard(20);

    delete ptr_landOwner1;
    delete ptr_landOwner2;
    delete ptr_landOwner3;
    return 0;
}

 this指针暂时跳过

 

运算符重载

////Integer.h////
#ifndef INTEGER_H
#define INTEGER_H

//我们自己定义的整形类,将整形封装成类,以便实现面向对象的封装



class Integer
{
    public:
        Integer();
        Integer(int value) : m_value(value){}
        //重载"+"号运算符
        Integer operator + (Integer other);

        int IntValue(){return m_value;}



        virtual ~Integer();

    protected:

    private:
        int m_value;  //实际的整形数字(member)
};

#endif // INTEGER_H



////Integer.cpp
#include "Integer.h"

//调用默认构造时,会为私有m_value赋一个默认值为0
Integer::Integer() : m_value(0)
{
    //ctor
}


//重载"+"号运算符
Integer Integer::operator + (Integer other)
{
    Integer result(this->m_value + other.m_value);  //用来返回的结果对象
    return result;
}


Integer::~Integer()
{
    //dtor
}



////main.cpp////
#include <iostream>
#include "Integer.h"

using namespace std;

void TestInteger();

int main()
{
    //cout << "Hello world!" << endl;
    TestInteger();
    return 0;
}


void TestInteger()
{
    Integer int1(1024), int2(2048), int3;
    int3 = int1 + int2;
    cout << "int3 = int1 + int2的结果为:" << int3.IntValue()<< endl;

}

const详解

////ConstDemo.h////
#ifndef CONSTDEMO_H_INCLUDED
#define CONSTDEMO_H_INCLUDED
#include <iostream>
using namespace std;

////程序有错,待排查
////一.const修饰成员变量
//void ConstDemo1()
//{
//    int num1 = 1024;
//    const int num2 = 1111;
//    //num2 = 2048;   //error: assignment of read-only variable 'num2'
//    const int * ptr1_num1 = &num1;
//    int const * ptr2_num1 = &num1;
//    ptr_num1 = &num2; //合法
//    *ptr1_num1 = 1024; //不合法
//    //const修饰指针变量时:
//    //1.只有一个const时,如果const位于*左侧
//    //表示指针所指的数据是常量,不能通过该指针修改实际数据
//    //指针本身是变量,可以本身指向其他内存单元
//    //2.只有一个const时,如果const位于*号右侧
//    //表示指针本身是常量,不能指向指向其他内存单元
//    //所指向的数据可以修改
//    int * const ptr3_num1 = &num1;
//    //ptr3_num1 = ptr2_num1; //不合法
//    //3.如果有两个const位于*号的左右两侧
//    //表示指针和指针所指向的数据都不能修改
//
//
//}
//

//二、const修饰函数参数

int core;

void ConstDemo2(const int num)
{
    //num = 123;   //传递来的参数num在函数体内不可改变,与修饰变量时的性质一致
}

class Computer
{
public:
    Computer(int m_core){this->m_core = core;}

    void buy() const{}
    void buy(int core)
    {

    }

    ///修改电脑的核心频率
    void SetCore(int core) {this->m_core = core;}
    void GetCore() const {return m_core;}

private:
    int m_core;  //CPU的主频
};


 void ConstDemo3(const Computer & computer)
{
    //const修饰引用时,不能修改引用对象的任何成员
    //好处是可以保护传递参数:不需要一个新的参数副本
    //使用const传递对象的引用时,可以起到不copy对象的目的(节省效率)

    //computer.buy(123);  //const成员函数不能调用非const成员函数
}


//三、const修饰返回值
//强调:使用const修饰引用类型的一个常用原因是:提高效率
const Computer & GetMax(const Computer & com1, const Computer & com2)
{
    Computer com3;
    if(com1.GetCore() > com2.GetCore())
    {
        com3 = com1;
        //return com1;
    }
    else
    {
        com3 = com2;
    }
    return com3;
}

//如果函数要返回局部对象,就应该直接返回这个对象,而不是要返回对象的引用
//在可以返回对象也可以返回引用时,就应该首选引用,因为效率高


//四、const修饰函数 —— 说明函数不会修改成员变量的值

class TestClass
{
public:
    int value;
    void ModifyValue() const
    {
        value = 1111;
    }
};


#endif // CONSTDEMO_H_INCLUDED

 

 

 

 

 

 

 

 

面向对象之继承 

 

 

 

The end·····

posted @ 2020-01-03 21:12  今夕清欢  阅读(330)  评论(0编辑  收藏  举报