上学期学期末的时候C+老师布置了个 C+的实验,在CSDN记录了自己的过程,感觉这种记录的方式有利于自身学习。所以下学期的VC++实验课也决定在这里记录一下。这次布置的任务大概是两周完成6个实验,其中有大约二三十个实验供给备选。决定先按着顺序来每个都敲一次。作业3.15布置,3.28截止。(后面又推迟了两周…)由于前几日在肝java和Python的入门,所以拖延了几天才开始这次作业。现在是3.19晚八点,开始这次工作。大概规划是先花个一晚上去复习一下原来学过的C+知识,然后再去开始按从基础到提高的顺序来做这些题。
3.24,晚,前几日周末有事+打游戏什么的…所以差不多现在才复习完,学习的较浅,大概只到了结构体这里。现在开始肝。
1、
遇到问题,语法不熟写成了 delete p,然后百度去看delete p和delete p[]的区别。参考了下述文章,没看太懂但是自己理解为 某些时候delete p会出错,所以为了保险都写成delete p[]
https://blog.csdn.net/qq1012848571/article/details/51594294
https://blog.csdn.net/qq_36381573/article/details/100086804
第一版代码
#include<iostream>
using namespace std;
class PP
{
public:
PP(int num, double x1);
~PP();
double fun(int n1, double x);
void process();
void show();
private:
int n;
double x;
double* p;
};
PP::PP(int num, double x1)
{
n = num;
x = x1;
p = new double(n);
}
PP::~PP()
{
if (p)
delete p;
}
double PP::fun(int n1, double x)
{
if (n1 == 0)
return 1;
else if (n1 == 1)
return x;
else if(n1>1)
return (((2 * n - 1) * x * fun(n1 - 1, x) - (n - 1) * fun(n1 - 2, x)) / n); //atFuRYh
}
void PP::process()
{
for (int i = 0; i < n; i++)
p[i] = fun(i, x);
}
void PP::show()
{
cout << "n=" << n << endl;
cout << "x=" << x << endl;
for (int i = 0; i < n; i++)
{
cout << p[i] << " " ;
if (i / 4 == 0)
cout << endl;
}
}
int main()
{
int n;
double x;
cin >> n >> x;
PP item(n,x);
item.process();
item.show();
return 0;
}
遇到问题,报错C26451。。。然后给我莫名其妙终止了调试。。
百度解决了C26451的问题。参考此文
https://www.zhihu.com/question/352977886
其中第二个回答
https://blog.csdn.net/mmk27_word/article/details/84378346
还在这里看了下int和double的数据存储范围
大概理解下来是int的存储范围比double小,编译器认为既然要转成double,那可能在过程中就会出现int放不下了的情况。所以报错。
修改方案是把代码中的int,改为了double,但这样和题意不符了…可我也不知道咋搞所以就这样吧。
- 补充:把报错那行代码中的n1全部强制转换成double型,就解决报错了。
还触发了“未加载wntdll.PDB”。。。。。参考各种文章找不到原因。。。
还触发这个bug,这bug我都不知道该去百度搜索什么。
肝不动了。。第一道题干了我两三个小时,还没解决。主要问题还是出现在这个对话框报错。。。百度的半天告得我大概意思是内存出了问题,后悔上学期没好好学啊呜呜,完全不懂。简单修改了几个代码中的bug后就搁置了,日后再看。
修改:
构造函数中内存空间改为 p = new double(8*double(n));`
析构函数改为
if (p)
{
delete[]p;
p = NULL;
}
但依旧没解决问题。。3.25凌晨2:14,sleep。
3.25下午继续开搞
2、
这个代码前几天帮别人看了下,敲过一次。所以做起来较快。第一版
#include<iostream>
using namespace std;
class SP
{
public:
SP(int n1, int k1);
int power(int m, int n);
~SP();
int fun();
void show()
{
cout << SP::fun << endl;
}
private:
int n ,k;
};
SP::SP(int n1, int k1)
{
n = n1;
k = k1;
}
//SP::~SP()
//{
//}
int SP::power(int m, int n)
{
int x=m;
for (int i = 1; i < n; i++) //atFuRYh
x *= m;
return x;
}
int SP::fun()
{
int y;
for (int i = 1; i <= n; i++)
y += power(i, k);
return y;
}
int main()
{
SP s(3,4);
s.show();
return 0;
}
遇到了这样一个报错
错误 C3867 “SP::fun”: 非标准语法;请使用 “&” 来创建指向成员的指针
经过检查发现是fun没加(),修改之后最终代码如下
#include<iostream>
using namespace std;
class SP
{
public:
SP(int n1, int k1);
int power(int m, int n);
/*~SP();*/
int fun();
void show();
private:
int n ,k;
};
SP::SP(int n1, int k1)
{
n = n1;
k = k1;
}
//SP::~SP()
//{
//} //atFuRYh
int SP::power(int m, int n)
{
int x=m;
for (int i = 1; i < n; i++)
x *= m;
return x;
}
int SP::fun()
{
int y = 0;
for (int i = 1; i <= n; i++)
y += power(i, k);
return y;
}
void SP::show()
{
cout << "n=" << n << "k=" << k << endl;
cout << "Fx=" << SP::fun()<<endl;
}
int main()
{
int a, b;
cout << "请输入n和k的值" << endl;
cin >> a >> b;
SP s(a,b);
s.show();
return 0;
}
3.25晚,3t
3、
下午写了一半出去了,晚上接着肝。第一版代码
#include<iostream>
using namespace std;
class MOVE
{
public:
MOVE(float b[], int m);
void average()
{
float sum = 0, ave;
int max = 0, min = 0;
for (int i = 0; i < MOVE::n; i++)
sum += MOVE::array[i];
ave = sum / MOVE::n;
cout << "数组中元素的平均值是:" << ave << endl;
int j = 0;
float k[20];
for (int i = 0; i < MOVE::n; i++)
if (MOVE::array[i] <= ave)
{
k[j] = MOVE::array[i];
j++;
}
for (int i = 0; i < MOVE::n; i++)
if (MOVE::array[i] > ave)
{
k[n-1-j] = MOVE::array[i];
j++;
}
for (int i = 0; i < n; i++)
MOVE::array[i] = k[i];
}
void print();
~MOVE();
private:
float array[20];
int n;
};
MOVE::MOVE(float b[], int m) //m为数组中元素个数
{
n = m;
for(int i=0;i<m;i++)
MOVE::array[i] = b[i];
}
MOVE::~MOVE()
{
}
void MOVE::print()
{
for (int i = 0; i < n; i++)
cout << MOVE::array[i] << endl;
}
int main()
{
float z[] = { 21,65,43,87,12,84,44,97,32,55 };
MOVE c(z, 10);
c.average();
c.print();
return 0;
}
运行后错了。。结果如图
看来还错的挺离谱。。。一来我把大的放到了左边,二来后面那半部分也在出错。
调试检查了一下,发现第二个语句中的j++应该改成j–.按照先前语句,我将新数列中的1234位置赋值成了小的,但又将他们替换成了大的。所以1234输出大,5678输出乱码。
最终代码如下
#include<iostream>
using namespace std;
class MOVE
{
public:
MOVE(float b[], int m);
void average();
void print();
~MOVE();
private:
float array[20];
int n;
};
MOVE::MOVE(float b[], int m) //m为数组中元素个数
{
n = m;
for(int i=0;i<m;i++)
MOVE::array[i] = b[i];
}
MOVE::~MOVE()
{
}
void MOVE::print()
{
for (int i = 0; i < n; i++)
cout << MOVE::array[i] << endl;
}
void MOVE::average()
{
float sum = 0, ave; //ave为平均值
for (int i = 0; i < MOVE::n; i++)
sum += MOVE::array[i];
ave = sum / MOVE::n;
cout << "数组中元素的平均值是:" << ave << endl;
int j = 0; //新建一个数组k,和数字j用于赋值。将原数组中的值按照要求赋到新数组中atFuRYh
float k[20];
for (int i = 0; i < MOVE::n; i++)
if (MOVE::array[i] <= ave)
{ //赋值小的
k[j] = MOVE::array[i];
j++;
}
for (int i = 0; i < MOVE::n; i++)
if (MOVE::array[i] > ave) //赋值大的
{
k[n - 1 - j] = MOVE::array[i];
j--;
}
for (int i = 0; i < n; i++)
MOVE::array[i] = k[i];
}
int main()
{
float z[] = {1.3,6.2,3,9.1,4.8,7.4,5.6,9.2,2.3};
int n = sizeof(z) / sizeof(float);
MOVE c(z, n);
c.average();
c.print();
return 0;
}
4、
这个代码一次成功了,其实一次成功的主要原因还是前面第三个的时候看错题在那里调了半天第四题23333.上代码
#include<iostream>
using namespace std;
void swapp(int& a, int& b) //定义函数用于交换最大最小值
{
int t;
t = a;
a = b;
b = t;
}
class MOVE
{
public:
MOVE(int b[], int m);
~MOVE();
void exchange();
void print();
private:
int* array;
int n;
};
MOVE::MOVE(int b[], int m)
{
n = m;
array = new int[m]; //参考自百度,应分配内存。
for(int i=0;i<m;i++)
MOVE::array[i] = b[i];
}
void MOVE::exchange()
{
float sum = 0, ave; //ave为平均值
for (int i = 0; i < MOVE::n; i++)
sum += MOVE::array[i];
ave = sum / MOVE::n;
cout << "数组中元素的平均值是:" << ave << endl;
int max = 0, min = 0;
for (int i = 0; i < n - 1; i++) //找最大值的下标 atFuRYh
if (MOVE::array[i] > MOVE::array[max])
{
max = i;
}
for (int i = 0; i < n - 1; i++)
if (MOVE::array[i] < MOVE::array[min])
{
min = i;
}
swapp(MOVE::array[max], MOVE::array[min]);
}
void MOVE::print()
{
for (int i = 0; i < n; i++)
cout << MOVE::array[i] << endl;
}
MOVE::~MOVE()
{
delete[]array;
}
int main()
{
int z[] = { 21,65,43,87,12,84,44,97,32,55 };
int n = sizeof(z) / sizeof(int);
MOVE a(z, n);
a.exchange();
a.print();
return 0;
}
不过还有个问题就是我标注了百度的那里,没懂为什么指针形式写的数组就得开辟下内存。。这两种的区别还是模糊的。后续去看看
昨日打游戏,今日一天有事…现在是3.27晚九点半,开始继续肝。由于一些原因,所以先做24和26。
24、
这个题需要生成随机数,记得原来看网课时候提到过什么真假随机数,但具体的忘了,所以去百度了一番。具体学习笔记在我另一篇文章记录。
https://blog.csdn.net/Ws_Te47/article/details/115273146
由于做的时候忘了记录…所以就直接贴上最终版修改完的代码。
#include<iostream>
#include<ctime>
using namespace std;
/*此题题意不明,未能理解为何数组中的数是随机生成的,又要去初始化date。
因此此题的解题为我所理解下的情景,即 随机生成一个25的数组,并统计。
此种情况下NUM析构函数传入的date与结果无关*/
class NUM
{
public:
NUM(int data);
void process();
void print();
private:
int data[25];
int num[10] = {}; //将数组中元素全部初始化为0
};
NUM::NUM(int data)
{
srand((unsigned int)time(NULL)); //在此进行随机数的生成 atFuRYh
for (int i = 0; i < 25; i++)
NUM::data[i] = rand()% 10 ;
}
void NUM::process()
{
for (int j = 0; j < 25; j++) //遍历25个元素,并统计其个数。没有想到循环的解决方案,所以使用了switch语句
switch (NUM::data[j])
{
case 1:
NUM::num[1] += 1;
break;
case 2:
NUM::num[2] += 1;
break;
case 3:
NUM::num[3] += 1;
break;
case 4:
NUM::num[4] += 1;
break;
case 5:
NUM::num[5] += 1;
break;
case 6:
NUM::num[6] += 1;
break;
case 7:
NUM::num[7] += 1;
break;
case 8:
NUM::num[8] += 1;
break;
case 9:
NUM::num[9] += 1;
break;
case 0:
NUM::num[0] += 1;
break;
}
}
void NUM::print()
{
cout << "随机生成的数组为" <<endl ;
for (int i = 0; i < 25; i++)
{
if (i % 5 != 0)
cout << NUM::data[i]<<" ";
else
{
cout << endl;
cout << NUM::data[i] << " ";
}
}
cout << endl;
cout << "数组中每个数字出现的次数为" << endl;
for (int i = 0; i < 10; i++)
{
if (i % 5 != 0)
cout << NUM::num[i] << " ";
else
{
cout << endl;
cout << NUM::num[i] << " ";
}
}
}
int main()
{
NUM aa(1); //此处传入的值无用
aa.process();
aa.print();
return 0;
}
然后这其中统计出现个数那里用到了switch语句,这个语句不常用而且仿佛网上说不建议用。我最初也是想用双重循环来解决,但无果。所以换了这个语句。虽然可能不好但好歹程序是跑起来了吧哈哈。
另一个就是我代码中注释那里写到的,因为这个题的题目我没太理解清楚,感觉像是他些许的设计不合理。所以我就按照我理解的来进行的编程。
26、
这道题和24有些许相似,都是要用到随机数。但这个题是让根据ASCII进行排序。经过百度得知,无法随机生成字符串,只能随机生成数字再转换成字符串。因此就根据这个思路生成了ASCII相应范围内的数字,排序后再强制转换成字符。排序部分偷懒用了sort函数。代码如下
#include<iostream>
#include<ctime>
#include <algorithm>
using namespace std;
class num
{
public:
num(int data);
void process();
void print();
private:
int data[25];
};
num::num(int data)
{
srand((unsigned int)time(null)); //在此进行随机数的生成 atfuryh
for (int i = 0; i < 25; i++)
num::data[i] = rand()% 94+33 ;
}
void num::process()
{
sort(num::data,num::data+25); //利用了c++内置函数,sort,进行排序
}
void num::print()
{
cout << "随机生成的字符为" <<endl ;
for (int i = 0; i < 25; i++)
{
if (i % 5 != 0)
cout << char(num::data[i])<<" "; //将ascii强制转换为字符
else
{
cout << endl;
cout << char(num::data[i]) << " ";
}
}
}
int main()
{
num aa(1); //此处传入的值无用
aa.process();
aa.print();
return 0;
}
2021.3.29晚,继续开搞。
5、
这个题让求绝对回文数,我的设想是先写一个十进制时候判断的函数,再转换成二进制后调用一次这个函数进行判断。两次判断均true则是绝对回文数。
百度得知没有转换二进制的函数,得自己编写。所以就copy了一部分。
https://blog.csdn.net/qq_41446560/article/details/80034932
转换为二进制函数copy于此,但还是改进了一些
copy的这个函数是转换后输出,我需要的则是return转换后的值。所以得改进一下。
思索良久没有想出来怎么把返回的值改成我一堆二进制数。。。。所以放弃这个想法,,决定直接在需要的地方用转换后的数组进行操作。
编写判断是否为回文数的代码,参考此文
https://blog.csdn.net/qq_36499686/article/details/79405005
之后去编写绝对回文数的代码,发现调用回文数代码还是得需要返回二进制的数。所以又返回上面步骤去改这个转换二进制的代码,改完如下。
int Er(int x)
{
int i, j, k = 0;
int a[1000];
i = x;
while (i)
{
a[j] = i % 2;
i /= 2;
j++;
}
for (int i = 0; i < j; i++)
k = k * 10 + a[i];
return k;
}
第一版最终代码如下
#include<iostream>
using namespace std;
int Er(int x)
{
int i, j, k = 0;
int a[1000];
i = x;
while (i)
{
a[j] = i % 2;
i /= 2;
j++;
}
for (int i = 0; i < j; i++)
k = k * 10 + a[i];
return k;
}
int Hw(int x) //用于判断一个数是不是回文数
{
int m = x; //m为原来的数,n为转换后的数
int n = 0;
while (m>0)
{
n = n * 10 + n % 10;
m /= 10;
return m == n; //此处受到百度的启发,直接返回此式。若相等则true反之则false
}
}
class Palindrome
{
public:
~Palindrome();
Palindrome(int x);
void huiwen();
void show();
private:
int n;
int y;
};
Palindrome::Palindrome(int x)
{
y = 0;
n = x;
}
Palindrome::~Palindrome()
{
}
void Palindrome::huiwen()
{
int o = 0; //只有所求数在十进制和二进制中均为回文数,才是绝对回文数。所以我定义一个o为0,若在一个中是则o+1,当o=2时说明两者皆是。
if (Hw(n))
o += 1;
if (Hw(Er(n)))
o += 1;
if (o == 2)
cout << n << "(" << Er(n) << ")" << endl;
else
cout << "NO" << endl;
}
void Palindrome::show()
{
}
int main()
{
Palindrome test(10);
test.huiwen();
return 0;
}
不过这个版本代码有个问题,就是没按照题意,将cout放在show函数中,而是放在了huiwen函数。不知道怎么改所以干脆索性不管了- -。
提示报错有个没初始化内存,这里算是一个教训,记得创建完数组后加个空的大括号,表示全部初始化为0。
网上找到,1–1000内的绝对回文数有
1
3
5
7
9
33
99
313
585
717
试了一下,1时候OK,剩下就报错了。。所以开始调试。
调试发现,是Hw函数中的这句出了问题。
n = n * 10 + n % 10;
修改:最后那个n改为m, 然后return m==n
的那个大括号也加错位置了。
然后。。。不该returnm==n
,因为m
的值已经改动过了,应该return n==x
修改后最终版如下
#include<iostream>
using namespace std;
int Er(int x)
{
int i=0, j=0, k = 0;
int a[1000] = {};
i = x;
while (i)
{
a[j] = i % 2;
i /= 2;
j++;
}
for (int i = 0; i < j; i++)
k = k * 10 + a[i];
return k;
}
int Hw(int x) //用于判断一个数是不是回文数
{
int m = x; //m为原来的数,n为转换后的数
int n = 0;
while (m>0)
{
n = n * 10 + m % 10;
m /= 10;
}
return x == n; //此处受到百度的启发,直接返回此式。若相等则true反之则false
}
class Palindrome
{
public:
~Palindrome();
Palindrome(int x);
void huiwen();
void show();
private:
int n;
int y;
};
Palindrome::Palindrome(int x)
{
y = 0;
n = x;
}
Palindrome::~Palindrome()
{
}
void Palindrome::huiwen()
{
int o = 0; //只有所求数在十进制和二进制中均为回文数,才是绝对回文数。所以我定义一个o为0,若在一个中是则o+1,当o=2时说明两者皆是。//atFuRYh
if (Hw(n))
o += 1;
if (Hw(Er(n)))
o += 1;
if (o == 2)
cout << n << "(" << Er(n) << ")" << endl;
else
cout << "NO" << endl;
}
void Palindrome::show()
{
}
int main()
{
Palindrome test(99);
test.huiwen();
return 0;
}
然后后面那些基础题暂且懒得写就不准备写了2333,开始搞提高部分的题
B1、
这个题看的很复杂…感觉偏向实际应用了 - -。所以按着一步一步来。
第一个惊奇发现是变量名居然可以设置中文(VS 2019)
成员名设置了中文没报错哦,然后main函数调用时输入.之后需要多点一下。如图那个加号,点开就有中文名。
按照猜测,这些数据应该都是私有成员。然后通过函数写入数据。
当我激动的敲完好几个录入函数的代码后发现题目要求是一个函数录入…我陷思,哎。
第一次敲这种项目,有点思路但些许乱不知道怎么串起来。所以决定先去看看b站教程,学习一下。准备看的是黑马程序员的一个案例。
4月9日 前一个星期大概一半时间在放假玩耍,剩下一半时间去肝了这个实验。参考着B站那个通讯录案例来做这个,但发现好多不同、问题,被一个静态常量卡了好久,与舍友商讨,百度无果后放弃…决定先去做后面有没有简单的
4月13日 最近其他事情好多…所以暂且放弃了继续做这个,先去做其他重要的事情,日后再回来练习C++吧…
本次vc作业主要是捡起了一些放下的东西吧,顺带复(预)习了一通好久没看的C+。主要遇到的问题集中在了内存…这就坚定了我啃一下CSAPP的决心…祝自己好运。