C++:简单计算器与排序

两个小程序

包含两个小程序,一个对数字进行计算的(也可以对其他可用类型),第二个是排序的.

C++.
image-2210

计算的小程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Example program
#include <iostream>
#include <string>
#include <functional>
using namespace std;

//加减乘除运算.

int main()
{
    /*
     template <class T> struct plus {
  T operator() (const T& x, const T& y) const {return x+y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef T result_type;
   };

   例如:上面是plus的原型,可以看出其中重载了加法运算.(其他的类似)
   更多可以参考:http://www.cplusplus.com/reference/functional/plus/ [应查看c++ 11的示例]
     */
    plus<int> age;
    minus<int> gre;
    multiplies<int> nums;
    divides<int> ds;
    negate<int> ne;
    modulus<int> modu;
    ///////////////////////////////
    cout << "add:" << age(10,20) << endl;
    cout << "minus:" << gre(100,50) << endl;
    cout << "mulitplies:" << nums(50,100) << endl;
    cout << "divides:" << ds(100,2) << endl;
    cout << "negate:" << ne(100) << endl;
    cout << "modulus:" << modu(100,10) << endl;
    return 0;
}

逆序排序

下面的程序其实使用了上面程序中的匿名negate对象(negate会倒置传入的值).

negate原型如下:

1
2
3
4
5
6
template <class T> struct negate {
  T operator() (const T& x) const {return -x;}
  typedef T argument_type;
  typedef T result_type;
};
//更多可参考:http://www.cplusplus.com/reference/functional/negate/

程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Example program
#include<iostream>
#include<algorithm>
#include<functional>
#include<vector>
using namespace std;


//逆序排列vector中的元素

int main()
{
  vector<int> vec={5,20,70,6,100,658,50,3,1558,1,85217,0};
  sort(vec.begin(),vec.end(),greater<int>());
  for_each(vec.begin(),vec.end(),[](const int &is){cout << is << " " ;});
    cout << endl;
  return 0;
}

C++:可调用对象与function

一点东西

题目也可以是函数表(用于存储指向可调用对象的”指针”).

1
2
3
4
5
6
7
8
9
10
11
//普通函数
int add(int i,int j){ return i+j; }
//lambda,其产生一个未命名的函数对象类.
auto mod = [](const int &i,const int &j){ return i+j; }
//函数对象类.
struct divide{
    int operator()(int denominator,int divisor)
    {
        return denominator / divisor;
    }
};

上面这些可调用对象,虽然类型不同,但是共享同一种调用形式:

1
        int(int,int)

可以定义一个函数表,用于存储指向这些可调用对象的”指针”.当程序需要执行某个特定的操作时,
从表中查找该调用的函数.

在C++中,函数表很容易通过map来实现.

简单意思就是将与int(int,int)一样的类型,放入一个map中,将其的操作作为map的主键.

形如:

1
2
3
4
map["+"]=add;//add是一个函数指针.
map["-"]=minus;//同add的含义一样.
map["*"]=..
以此类推..

C++.
image-2208

代码实现

下面的代码可以运行,推荐一个在线运行的网址:CPP.SH

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Example program
#include <iostream>
#include <string>
#include <map>
#include<functional>
using namespace std;

/*
//普通函数
int add(int i,int j){ return i+j; }
//lambda,其产生一个未命名的函数对象类.
auto mod = [](const int &i,const int &j){ return i+j; }
//函数对象类.
struct divide{
    int operator()(int denominator,int divisor)
    {
        return denominator / divisor;
    }
};

上面这些可调用对象,虽然类型不同,但是共享同一种调用形式:
        int(int,int)
       
可以定义一个函数表,用于存储指向这些可调用对象的"指针".当程序需要执行某个特定的操作时,
从表中查找该调用的函数.

在C++中,函数表很容易通过map来实现.

*/
int add(int i,int j){
    return i+j;
    }



struct divide{
    int operator()(int denominator,int divisor)
    {
        return denominator / divisor;
    }
};


int main()
{
    auto mod = [](const int &i,const int &j){ return i+j; };
  map<string,int(*)(int,int)> binops;
  binops.insert({"+",add});
  //但是我们不能将mod或者divide存入binops.因为mod不是一个函数指针.
  //问题在于mod是个lambda表达式,而每个lambda有它自己的类类型,该类型与存储在binops中的值得类型不匹配.
 
 
  //解决办法如下:
  //使用一个名为function的新的标准库类型解决上述问题.
 
  /*function<int(int,int)> f1 = add;//函数指针
  function<int(int,int)> f2 = divide();//函数对象类的对象.
  function<int(int,int)> f3 = [](int i,int j){ return i * j ; }; //lambda
 
  cout << f1(4,2) << endl;
  cout << f2(4,2) << endl;
  cout << f3(4,2) << endl;*/
 
  //使用function类型我们可以重新定义map.
  map<string,function<int(int,int)>> binops2={
      {"+",add},    //函数指针.
      {"-",std::minus<int>()},  //标准库函数对象
      {"/",divide()},   //用户定义的函数对象.
      {"*",[](int i,int j){ return i * j ;}}, //未命名的lambda
      {"%",mod} //命名了的lambda对象
      };
 
 
  cout << "10+5=" << binops2["+"](10,5) << endl;//调用add(10,5)
  cout << "10-5=" << binops2["-"](10,5) << endl;//调用minus<int>
  cout << "10/5=" << binops2["/"](10,5) << endl;//调用divide
  cout << "10*5=" << binops2["*"](10,5) << endl;//调用lambda
  cout << "10%5=" << binops2["%"](10,5) << endl;//调用lambda
  /*
  我们不能(直接)将重载函数的名字存入function类型的对象中:
 
 
  int add(int i,int j){return i+j;}
  Sales_data add(const Sales_data&,const Sales_data&);
 
  map<string,function<int(int,int)>> binops3;
  binops3.insert({"+",add}); //错误:哪个add?
 
 
  解决上述二义性的问题是存储函数指针而非函数的名字:
 
 
    int (*fp)(int,int) =add;    //指针所指的add是接受两个int的版本.
    binops3.insert({"+",fp});   //正确:fp指向一个正确的add版本
   
    同样,也可以用lambda来消除二义性:
   
    //正确:使用lambda来指定我们希望使用的add版本
    binops3.insert({"+",[](int a,int b){return add(a,b);}});
 
  */
 
 
  return 0;
}

Windows10:一些细节体验

简介及写在前面

如你所知,Windows10在10.1的时候发布了[关于下载和安装会在后面介绍].据说,微软直接跳过Windows9的原因,是因为和Windows98在程序验证的时候容易出错.所以就直接跳级到Windows10.

用了一年多的Windows8,对于Windows10一开始的期待还是很高的,但随着发布的临近也就没那么高的期待了.大部分原因是和Windows8没多少变化.如果你正在用Windows 8/Windows 8.1/Windows 8.1 Update这三个版本,那么你可以暂时不用升级了.

当Windows10默认把动态磁贴改小之后,就觉得不习惯了…仿佛Windows XP/7用户不习惯Windows 8没有开始菜单一样一样的……

欣赏图片

Windows10桌面
image-2192

Windows10桌面

Windows10的这台电脑
image-2193

Windows10的这台电脑

Windows10的版本信息
image-2194

Windows10的版本信息

Windows10自带的壁纸和Windows8的相似
image-2195

Windows10自带的壁纸和Windows8的相似

Windows10的搜索功能
image-2196

Windows10的搜索功能

Windows10的添加桌面功能,这个功能这次更加明显的放在任务栏上
image-2197

Windows10的添加桌面功能,这个功能这次更加明显的放在任务栏上

Windows10的虚拟键盘
image-2198

Windows10的虚拟键盘

Windows10上的IE版本
image-2199

Windows10上的IE版本

Windows10的应用商店
image-2200

Windows10的应用商店

Windows10的应用商店加载
image-2201

Windows10的应用商店加载

Windows10的开始菜单
image-2202

Windows10的开始菜单

安装和常见问题

Windows10官方安装码:NKJFK-GPHP7-G8C3J-P6JXR-HQRJR

关于镜像下载和其他问题可以参考:

Windows 10各版本下载
Windows 10安装问题及修复