想吧这个命名命名规范写到最前面,匈牙利命名法: 名字=属性+类型+对象描述
http://www.cnblogs.com/ggjucheng/archive/2011/12/15/2289291.html
2016.10.09
在一个函数中再次调用该函数的行为叫做递归,这样的函数被称作递归函数。
1、求5的阶乘。
demo.cpp
#include "GameFactorial.h"
using namespace std;
int main()
{
Game g1;
int a;
cout << "请输入想要的阶乘:" << endl;
cin >> a;
cout<<"该数的阶乘是:"<"pause");
}
GameFactorial.h
#include
#include
class Game
{
public:
int factorial(int a);
};
int Game::factorial(int a)
{
int Num;
Num = a;
if (Num==0 || Num==1)
{
return 1;
}
else
{
return Num*factorial(a - 1);
}
}
2016.10.10
栈(stack)是支持push和pop两种操作的数据结构,Push是在栈的顶端放入一组数据,pop是从其顶端取出一组数据的操作,栈叫做LIFO,Last In First Out 后进先出。
今天在南阳理工大学的ACM的OJ 平台上名注册了一个账号,还是很开心的,据说可以根据你的水平智能生成相应的算法,(@ο@) 哇~
附上链接:
http://acm.nyist.net/JudgeOnline/reg.php
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
char a, b, c,Max,Min,Mediate;
cin >> a >> b >> c;
if (a>=b)
{
if (b>=c)
{
Min = c;
Max = a;
Mediate = b;
}
else//C>B and A>B
{
if (a >= c)
{
Max = a;
Mediate = c;
Min = b;
}
else//a
{
Max = c;
Mediate = a;
Min = b;
}
}
}
else//b>a
{
if (a>=c)
{
Max = b;
Mediate = a;
Min = c;
}
else//C>a
{
if (b>=c)
{
Max = b;
Mediate = c;
Min = a;
}
else//C>b
{
Max = c;
Mediate = b;
Min = a;
}
}
}
cout << Min << " " << Mediate << " " << Max << " " << endl;
}
我在编译器里面是运行出来额,但是在OJ平台运行出错了
2016.10.14
在输出的时候,&符号叫做取地址
int Src_nNum = 1;
int &Src_nRNum = Src_nNum;//这个可以看做是一个简单的赋值操作
cout << Src_nRNum <<"\n"<< &Src_nRNum << "";//不加&的就是一个单纯的,加&输出的就是地址
X int &SrcNUm=1;//这是错误的,因为引用类型初始值必须是一个对象
习题:2.17
int i, &ri = i;
i = 5;
ri = 10;
cout << i << " " << ri << endl;
system("pause");
从这个地方可以看出赋值语句和引用语句的不同,引用的话,使得ri和I一直相互关联,其中任何一个值改变,另一个值也跟着改变。
int Src_nVal = 42;
cout << &Src_nVal << endl;
如果这样去做的就会报错。
//必须这样写
int *p=&a;
int &r=a;//这是声明的部分,表示的是r是一个引用
int *p;//这是声明部分,表示的p是一个指针
p=&a//&出现在表达式中,是一个取地址符号
*p*i//出现在表达式中,是一个解引用符号
int &r2=*p//&是声明的部分,表示r是一个引用,*是解引用符号
*相当于往上走 &相当于往下翻
int Src_nVal = 42;//这个地方42就叫做字面值
cout << &Src_nVal << " "<
int *p_Valp2 = p_Valp;
int *&r=p;//要理解r的类型,最简单的方法是:1、从右往左阅读;2、离变量名最近的符号(在此例中是&)对变量有最直接的影响,因此r是一个引用,声明符号的其他部分(此例中是*)表示r引用的类型,因此*符号说明,r引用的是一个指针。综上:r引用的是一个int类型的指针
const int &r=i;//将r2绑定对象i
指向常量的指针不能用于改变其所指对象的值,指针只是一个指向的关系。但是引用可以改变引用对象的值。
顶层const表示指针本身是一个常量;底层const表示指针所指的对象是一个常量
对象:是内存的一块区域
变量:就是命名后的对象或者引用
引用:某个对象的别名
指针:就是一个对象,存放着某个对象的地址
字面值:就是一个不能改变的值,例如:数字,字符等。其中单引号是字符字面值,多引号是字符串字面值
string line;
while (getline(cin,line))//getline的参数一个输入流一个是string对象,把输入流给了line
{
cout << line << endl;
}
system("pause");
string s1//初始化一个空字符串
string s2(s1)//s2是s1的副本
string s1=s2//s1是s2的副本
string s3(“value”)//s3的字面值是value 等价于string s3="value"
string s4(n,"c")//输出的n个c
string s
s.empty()//s为空的时候返回true,否则返回false
s.size()//返回s字符的个数
s[n]//返回s中的第N字符
s1+s2//将s1和s2两个字符连接在一起
使用范围for语句
for(declaration:expression)
statement //expression 表示的对象(一个序列)declaration 声明一个访问string的每个字符的变量
举例说明:
string Src_sStr("hello world!");
for (auto Srd_sBL : Src_sStr)
{
cout << Srd_sBL << "";
}
system("pause");
如果在这个例子中想要改变的是Src_sStr的值,就需要把Srd_sStr改成引用类型(加&)
string Src_sStr("hello world!");
for (auto &Srd_sBL : Src_sStr)
{
Srd_sBL = toupper(Srd_sBL);
}
cout << "Src_sStr:" << Src_sStr << "";
2016.10.13
C++primer
P90.3.3.1
vector<vector<int>>ivec;//定义了一个ivec的vector对象,其中每个ivec的每个元素都是vector类型
vector<string>{10,"hi"};//初始化10个hi,string只能用{}不能用()
解答:
#include
#include;
using namespace std;
int main()
{
vector<int> Ivec;
int i;
char cont = 'y';
cout << "Please Input The Num:" << endl;
while (cin >> i)//从这条语句中看出.pushback只能在最后面走
{
Ivec.push_back(i);
cout << "if you want to continue stop ,please input:n" << endl;
cin >> cont;
if (cont=='n'&&cont=='N')
{
break;//突然意识到break语句真伟大
}
}
for (auto nOutput:Ivec)//这里是一个冒号
{
cout << "The output is:" << nOutput <<" "<< endl;
}
system("pause");
}
这个程序有个小bug,但是这是我按照思路写的第一个小程序。
3.15跟这道题目类似。
3.16是在3.13的基础上
int VNum;
VNum = Ivec.size();//注意这个地方要写括号
cout << "The Num is:" << VNum << endl;
3.17
//答案里面有一个for语句来遍历每个字符串,然后toupper这个函数改为大写字母。
#include
#include
#include;
using namespace std;
int main()
{
vector<string>ISVec;
char ProEnd = 'n';
string SRecWord;
cout << "Please input a set of word:" << "";
while (cin>>SRecWord)
{
ISVec.push_back(SRecWord);
//定义中方法,先把输入的字符串都改成大写以后再输入到里面
//第二种方法,在输入之后想办法再改
cout << "If you want to stop Please input :N" << "";
cin >> ProEnd;
if (ProEnd =='n')
{
break;
}
for ( auto men:ISVec )
{
for (auto c:men)
{
c=toupper(c);
cout << "The Output is:" << c << endl;
}
}
}
system("pause");
}
程序依然是有BUG的
3.21使用迭代器在做一遍
for (auto it = ISVec.cbegin(); it != ISVec.cend() && !it->empty();++it)
{
cout << *it << endl;
}
将原来的额题目循环输出打印的地方换成这个就可以了
(*it).empty()等价于it->empty();
3.4-3.23
编写一个程序,创建一个含有10个整数的 vector对象,然后用迭代器吧所有的值都变为原来的两倍,并且输出vector对象的内容
vector<int> Src_iVec(10, 1);
for (auto _IOutPut : Src_iVec)
{
cout << _IOutPut * 2 << "";
}
容器:vector 和string 就是容器
迭代器:用于访问容器中元素 举个例子,就是上面这个_IOutPut就是迭代器
iter+n//迭代器指示的新位置比原来位置向前移动了n个元素
iter-n//向后移动N个元素
iter+=n//将iter+n的结果赋值给了iter
iter1-iter2就是iter1和iter2之间的距离
举例说明
vector<int>Src_nDouble{ 1, 2, 3, 4, 6, 7, 8, 9 };
for (auto Src_nDSing:Src_nDouble)
{
cout << Src_nDSing + 1 <<"";
}
3.4.2-3.24
读入一组整数,并把他们存入一个vector的对象中,
1、将每对相邻的整数的和输出。
2、改写程序,将第一个和最后一个元素的和输出,然后是输出第2和和倒数第2个数的和
3、输出一个容器偶数位
vector<int>Src_nDouble{ 1, 2, 3, 4, 6, 7, 8, 9 };
for (auto Src_nDSing:Src_nDouble)
{
for (int i = 0;i<2;i+=2)
{
cout << Src_nDSing + i + Src_nDSing + i+1<< endl;
}
}
这个程序数字不对,
3.5.5-3.41
编写一段程序,用整型数组初始化一个vector对象
int a[] = { 1, 2, 3, 4, 5, 6 };
vector <int> Src_nCSH(begin(a), end(a));//(a,b)a表示起始位置,b表示终止位置
for (auto Src_nXS:Src_nCSH)
{
cout << Src_nXS << "" ;
}
如果我想输出3,4,5
vector <int> Src_nCSH(a+2, a+5);
//需要注意的一点是:a+5在数组中指的是6,遍历的时候到6停止,6不输出
//定义一个3行4列,也就是3*4的二维数组
int a[3][4]={
{1,2,3,4},//第一行初始值
{1,2,3,4},//第二行初始值
{1,2,3,4}//第三行初始值
};
等价于
int a[3][4]={1,2,3,4,1,2,3,4,1,2,3,4};
int j,i=0;
j=i++;//输出结果是j=0,i=1;//用后自加1
int j,i=0;
j=++i;//输出结果是j=1,i=1;//用前自加1 这种方式尽量多使用
While(A)
{
B
}
如果满足A就进入循环体B
用While语句遍历vector中的元素
vector<int> Src_nUNZero{ 1, 2, 3, 4 };
auto Src_nUm = Src_nUNZero.begin();
while (Src_nUm!=Src_nUNZero.end())
{
cout << *Src_nUm++ << "";
}
条件运算符(?:)
cond?expr1:expr2;//
如果cond为真,就执行expr1;否则就执行expr2;
》》扩展:嵌套条件表达式
举例
string finalgrade=(grade>90)?"high pass"
:(grad<60)?"fail":"pass";
4.7-4.21
编写一段程序,使用条件运算符从vector中找出那些元素是奇数,并把这些奇数翻倍
vector<int> Src_nUNZero{ 1, 2, 3, 4 };
int vvale;
for (auto &men:Src_nUNZero)
{
vvale=(men % 2 == 0) ? men*2:men*9;
cout << vvale << endl;
++men;
}
看来这个程序通了,只是有点小bug
修改了一下,更加符合题意
vector<int> Src_nUNZero{ 1, 2, 3, 4 };
int vvale;
for (auto men:Src_nUNZero)
{
vvale=(men % 2 == 0) ? 0:men*2;//从这个程序中可以看出,表达式必须要翻倍
cout << vvale << "--";
++men;
}
cout <<((men % 2 == 0) ? 0 : men * 2) << "--";//终于知道原因了,因为这个地方如果我吧他们都括了括号,那么编译就可以通过了
输出的结果一样
1. ~,位求反,~a
2. <<,左移,a<;
3. >>,右移,a>>b
4. &,位与,a&b
5. ^,位异或,a^b
6. |, 位或,a|b
sizeof运算符返回是一个表达式,或者一个类型名字所占有的字节数
sizeof有两种表达形式
sizeof(类型)
sizeof 表达式
以上个题目为例
vector<int> Src_nUNZero{ 1, 2, 3, 4 };
for (auto men:Src_nUNZero)
{
cout <<((men % 2 == 0) ? 0 : men * 2) << "--";
++men;
cout << (sizeof(men)) << endl;
}
那么可以知道每个men占4个字节
逗号运算符含有两个运算对象,按照从左往右的顺序依次求值;逗号表达式通常被用在for循环语句中
for(a;b;C++,d--)
复合语句也叫做块,就是{ }里面东西就叫做块
5.3.2-5.9
编写一段程序,统计出cin读入的文本中有多少个元音字母。
char Srv_chName;
int a = 0;
while (cin >> Srv_chName)
{
if (Srv_chName == 'a' || Srv_chName == 'e' || Srv_chName == 'i' || Srv_chName == 'o' || Srv_chName == 'u' )
{
++a;
}
else
{
break;
}
}
cout << a << "";
依然这段程序有个小bug
按理说,应该是是5个,
int a = 0;
char Srv_chName1;
while (cin>>Srv_chName1)
{
switch (Srv_chName1)
{
case 'a':case 'e':case 'o':case 'i':case 'u'://
++a;
default:
break;
}
cout << a << endl;
}
程序仍然有个小BUG
迭代语句通常称为循环
异常是指存在于运行时的反常行为
异常处理机制主要包括:程序中异常检测和异常处理
throw SamNUm("输入的数字不是相同的");
try{
////请正确输入}
catch(runtime_error)
{///请用户重新检查输入后重新输入
char c;
cin>>c;
}
函数的三要素:返回类型,函数名,形参类型
形参出现在函数定义的地方,实参出现在函数调用的地方;实参是形参的初始化
auto func(int i )->int (*)[10];//func接受了一个int类型的实参,返回一直指针,这个指针有10个整数的数组//说心里话,我也不明白这说的是什么话
定义:同一作用域内的名字相同,但是形参列表不同的函数
#include
#include
#include
#include
using namespace std;
void Function1(int a,int b);//函数1的声明
void Function1(char a, char b);//函数2的声明
int main()
{
Function1(1, 2);
Function1('a', 'b');
system("pause");
}
void Function1(int a, int b)//函数1的定义
{
cout << "这是调用的第一个函数" << endl;
}
void Function1(char a, char b)//函数2的定义
{
cout << "这是调用的第二个函数" << endl;
}
这个小程序还是比较满意的
//目前暂定是这方法
#include
#include
using namespace std;
int main()
{
clock_t start, finish;
start = clock();
cout << "HW .... " << endl;
finish = clock();
cout << finish - start << "/" << CLOCKS_PER_SEC << " (s) " << endl;
system("pause");
}
内联函数就是函数部分放到main函数内部去执行
内联函数适合那种函数规模比较小的函数。
函数指针指向的是函数(而不是对象),函数的类型是由它的返回类型和形参共同决定的,与函数名无关。
构造函数作用就是初始化类的对象的数据成员
友元的关键字是friend
通常用于输出程序的错误消息,写入到标准错误
继承可以让我们声明一个特定的类继承自另一个类
cout << "hi" << flush;//输出hi然后刷新缓冲区,不附加任何额外的字符
cout << "hi" << endl;//输出一个hI和一个换行,然后刷新缓冲区
cout << "hi" << ends;//输出一个hi和一个空额,然后刷新缓冲区
cout << unitbuf;//所有输出操作后都会立即刷新缓冲区
cout<//回到正常的缓冲方式
容器的size是指,容器已经保存的元素的数目
容器的capacity是指,在不分配新的内存空间的前提下,它最多可以保存的元素数目
vector//可变数组大小,支持快速随机访问,在尾部以外的地方插入比较缓慢
deque//双端队列,支持快速随机访问,在头部和尾部插入数据比较快
list//双向链表,支持双向顺序访问,在任何位置进行插入和删除都比较快,不支持元素的随机访问
forward_List//单向链表,支持单向顺序访问,在链表任何位置都比较块,不支持元素的随机访问
array//固定大小数组。支持快速随机访问,不能添加和删除元素
string//与vector相似的容器,专门用于保存字符
c.begin(),c.end()//返回指向C的首个元素和末尾元素位置之后的迭代器
c.cbegin(),c.cend()//访问的const_interator
swap用来交换两个类型相同的容器的内容
Vector <string> svec1(10);
vector <string> svec2(21);
swap(svec1,svec2);
.push_back(t)//在容器的尾部添加元素t
.push_front(t)//在容器的顶部部添加元素t
.insert(p,t)//具体怎么用,我也不知道
.back()
.front()
[n]//对下标为n的元素进行引用
.pop_back()//删除容器的最后一个元素
.pop_front()//删除容器第一个元素
.erase(p)//删除迭代器P所指定的元素
.clear()//清除容器中所有元素
//array不支持resize
.resize(n)//如果当前值大于n,就会把末尾的值删掉,如果小于n,就会在末尾增加元素
.resize(n,p)//增加的元素是P
容器的size是指的它已经保存了元素数目,而capacity则实在不分配新的内存空间的前提下,它最多可以保存的元素
string s(cp,n)//cp是数组名,n是数组中前n个元素,s相当于一个实例化的对象
substr把原始string的一部分进行拷贝
s.substr(pos,n)//返回值是s中从pos开始的n个字符的拷贝,pos默认值为0;
.insert()
.erase()
.assign()
.replace()
s.find(a)查找s中a第一次出现的位置,也就是说是返回值是一个数字
s.rfind(a)查找s中a最后一次出现的位置
s.find_first_of()
s.find_last_of()
s.find_first_not_of()
s.find_first_not_of()
int i = 42;
string s = to_string(i);//将整型数i转化成string类型
double d = stod(s);//将字符串s转换成浮点类型
#include
#include
#include
using namespace std;
int main()
{
vector<int> Src_nVector{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int sum = accumulate(Src_nVector.cbegin(), Src_nVector.cend(), 0);//accumulate函数定义在头文件numeric中,第一参数是容器的起始位置,第二个参数是容器的末尾,最后一个sum的初始值
cout << sum << endl;
system("pause");
}
运行的结果图:
back_inserter是一种插入迭代器(也叫做迭代器适配器),向容器中添加元素,它定义在iterator的头文件中
关联容器支持高效关键字查找和访问,两个主要的关键容器类型map和set
标准库提供了8种关联容器
map//关键字和值之间要一一对应的集合,也叫做关联数组,关联数组与正常数组之间的差别在于,关联数组下标可以不是整数
set//只含有关键字
multimap//关键字可以重复出现额map
multiset//关键字可以重复出现的set
unordered_map//用哈希组织的map
unordered_set//用哈希组织的set
unordered_multimap//用哈希组织的map,关键字可以重复出现
unordered_multiset//用哈希组织的set,关键字可以重复出现
我梳理了一下我知识结构:
pair的标准库类型定义在头文件utility中
hash是一种特殊额标准库模板,无序容器用他来管理元素的位置
将给定类型的数值映射到整型值的函数,相同的值必须映射到相等的整数,不相等的值映射到不相等的整数
Weak_ptr是一种不控制所指向对象生存期的智能指针
int *p= new int[get_size()]//【】中的数大小必须是常量,但是不必是常量
注意:不能对动态数组调用begin或者end