vector
,达到透明化的目的。我们可以操作指针(代表某特定内存地址),不需要直接操作对象。之前了解了如何定义一个对象:
int ival=1024;
指针内含某特定类型对象的内存地址。如果我们要定义某个特定类型的指针时,必须在类型名称之后加上*
:
int *pi;//pi是个int类型对象的指针
如果我们希望去的对象所在的内存地址而不是对象值,应该使用取址运算符&
int *pi=&ival;//将pi的初试值设为ival所在的内存地址
如果要访问一个由指针所指的对象,我们可以对该指针进行提领,即取得“位于该智能所指内存地址上”的对象,在指针之前使用*
:
if(*pi!=1024)//读取vial值
*pi=1024;//写值到vial
指针总结:
1、指针含义说明
pi;//表示pi所代表的内存地址
*pi;//表示vial的值
2、指针可能不指向任何对象,程序运行时可能发生错误,也就是野指针。一个未指向任何对象的指针,它的地址一般为0,也称之为null指针、野指针,所以我们可以对指针进行初始化:
int *pi=0;
案例:
我们定义6个vector对象(代表六个数列):
vector<int> fibonacci,Lucas,Pell,Triangular,Square,Pentagonal;
我们用一个指针来指向一个“元素类型为int”的vector,形式为:
type_of_object_pointer_to *name_of_pointer_object
type_of_object_pointer_to:数据类型
name_of_pointer_object:对象名
我们用来指向vector
,则命名我pv
,初值为0。
int *pv=0;
这种方式可以依次指向数列的vector
,比较繁琐,会牺牲程序的透明性。那么,另一种方案就是将每个数列的内存地址存入vector
中,我们可以通过索引的方式,透明访问这些数列:
const int seq_cnt=6;
//定义指针数组,长度为6
//每个指针都指向vector对象
vector<int> *seq_addrs[seq_cnt]={
&fibonacci,&Lucas,&Pell,
&Triangular,&Square,&Pentagonal;
}
其中,seq_addrs
表示array
,元素类型为vector
,seq_addrs[0]
则表示fibonacci vector
的地址。因此,我们可以通过索引值的方式,不通过名称来访问每个vectir:
vector<int> *current_vec=0;
for(int i=0;i<seq_cnt;i++){
current_vec=seq_addrs[i];//所有要显示的元素通过current_vec访问
}
最后,主要解决顺序问题。之前用户总是依据fibonacci,Lucas,Pell,Triangular,Square,Pentagonal的顺序进行猜测。我们希望数列随机出现,这里用到了C语言标准库中的rand()
和srand()
函数:
#include
srand(seq_cnt);//srand()的参数是随机数生成器的种子
seq_index=rand()%seq_cnt;//rand()会返回“0-int所能表示最大数”的一个整数,我们的索引在0-5之间,索引采用取余的方式。
current_vec=seq_addrs[seq_index];
}
两个函数必须使用cstdlib
头文件
下面就是依据上一篇文章进行改进的代码:
#include
#include
#include
#include
using namespace std;
int main() {
int usr_guess; //用户猜测的数字
bool num_seq = true; //显示下一组数列
bool guess_again = true; //用户想再猜一次
int guess_num = 0; //用户猜的总次数
int guess_right = 0;//用户猜对次数
char usr_rsp; //用户的回答 内循环用
char try_again; //用户的回答 外循环用
double usr_score = 0.0;//评分比值,采用double双精度类型
const int max_tries = 3;//设置最多猜测次数
const int seq_size = 18;//设置数列最大长度
int elem_seq[seq_size] = { //每个数列存储前三个数字进行猜测
1,2,3, //Fibonacci(斐波那契)
3,4,7, //Lucas(卢卡斯)
2,5,12, //Pell
3,6,10, //Triangular
4,9,16, //Square
5,12,22 //Pentagonal
};
//将每个数列前三个数存入vector
vector<int> fibonacci(elem_seq, elem_seq + 3);
vector<int> lucas(elem_seq+3, elem_seq + 6);
vector<int> pell(elem_seq+6, elem_seq + 9);
vector<int> Triangular(elem_seq+9, elem_seq + 12);
vector<int> Square(elem_seq+12, elem_seq + 15);
vector<int> Pentagonal(elem_seq+15, elem_seq + 18);
const int max_seq = 6;
string seq_names[seq_size] = {
"Fibonacci",
"Lucas",
"Pell",
"Triangular",
"Square",
"Pentagonal"
};
//将每个数列地址存入seq_addrs数组
vector<int> *seq_addrs[max_seq] = {
&fibonacci,&lucas,&pell,&Triangular,&Square,&Pentagonal
};
vector<int> *current_vec = 0;
int seq_index;
srand(max_seq);
while (num_seq == true) {
int try_cnt = 0;//猜的次数与最多次数比较
bool got_it = false; //用户是否猜对
//对数列进行随机化
seq_index = rand() % max_seq;
current_vec = seq_addrs[seq_index];//获取数列
//开始猜测数字
cout << "The first two elements of the squence are: "
<< (*current_vec)[0]<< ","
<< (*current_vec)[1] << "."
<< "\nWhat is the next element?\n";
//用户猜错且想再次猜
while (guess_again == true && got_it == false && (try_cnt++ <= max_tries))
{
std::cout << "please input your num:" << endl;
std::cin >> usr_guess;
guess_num++;
//如果猜正确
if (usr_guess == (*current_vec)[2]) {
std::cout << "Your guess is right!"
<< (*current_vec)[2]
<< " is the next element in the "
<< seq_names[seq_index]
<< " sequence.\n";
got_it = true;
guess_right++;
}
//用户猜错
else {
//判断猜的次数 switch
switch (try_cnt)
{
case(1):
std::cout << "Oops!Nice guess but not quiye it! \n" << endl;
break;
case(2):
std::cout << "Hmm.Sorry.Wrong a second time.\n" << endl;
break;
case(3):
std::cout << "Ah,this is harder than it looks.\n" << endl;
break;
default:
std::cout << "It must be getting pretty frustrating by now! \n" << endl;
break;
}
//是否再试一次
std::cout << "Error!Want to try again?(y/n):";
std::cin >> usr_rsp;
if (usr_rsp == 'N' || usr_rsp == 'n')
guess_again = false;
}
}//内层循环结束
std::cout << "want to try another sequence again?(y/n):";
std::cin >> try_again;
if (try_again == 'N' || try_again == 'n')
num_seq = false;
}//外循环结束
return 0;
}