0.展示PTA总分
1.本章学习总结
1.1 学习内容总结
- 指针与数组
数组的基地址是在内存中存储数组的起始位置,它是数组中的第一个元素(下标为0)的地址,因此数组名本身是一个地址即指针值。在访问内存方面,指针和数组几乎是相同的对于指针p,p=a+1是合法的,但是a=a+1就是不合法的。数组名可以使用指针形式,而指针变量也可以转换为数组形式。如果p和q是指向数组元素的指针,那么p-q产生一个int型的值,该值表示在p和q之间的数组元素的个数。两个相同类型的指针相减,表示台它们之间相隔的数组元素数目。使用数组和指针可以实现相同的操作,但是指针的效率更高,更加灵活。以下是对我上面的内容赋予的代码解释:
- 字符指针
对于字符串常量的存储。由于字符串常量是一串字符,通常被看做一个特殊的一维字符数组,与数组的存储类似,字符串常量中的所有字符在内存中连续存放。如果定义一个字符指针接收字符串常量的值,该指针就指向字符串的首字符。如果要改变数组所代表的字符串,只能改变数组元素的内容。如果要改变指针所代表的字符串,通常直接改变指针的值,让它指向新的字符串。为了尽量避免饮用未赋值的指针所造成的伤害,在定义指针时,可先将它的初值置为空。常用的字符串处理函数:1.字符串的输入和输出:scanf(格式控制字符串,输入参数表)printf(格式控制字符串,输出参数表)字符串输入函数gets(s)字符串输出函数puts(s)2.字符串的复制,连接和比较及字符串长度.代码:
- 指针做函数参数
在C语言中实参和形参之间的数据传递是单向的“值传递”方式,调用函数不能改变实参变量的值,当指针变量作为函数参数时也遵守这一规则。要通过函数调用来改变主调函数中某个变量的值,可以把指针作为函数的参数。在主调函数中,将该变量的地址或者指向该变量的指针作为实参。在被调函数中,用指针类型形参接受该变量的地址,并改变形参所指向变量的值。
- 二级指针、行指针
1、行指针:数据类型(*p)[m];
定义:指向由m个元素组成的一维数组的行指针变量
如下代码
经测试,不能直接指向一维数组
所谓“行指针”,二维数组a[2][3]来说,就指的是a[0],a[1]这两行,那么如果行指针加数字的话,如果p+1,那么这时指向的就是a[1],p本身指向的是a[0]。
通过不同的测试输出发现: (p+1)输出的是2,第一行的第二个元素。根据指针与数组的关系我们知道,数组名可以当成指针来用,而这里明显a[0]是第一行的一维数组名,也是第一行的首地址,参考第六个输出不难发现,这里的p可以换成a[0],即(a[0]+1),所以验证了上面的推测:*p = a[0]
对行指针,用上面那个例子来说:p其实是一个二级指针,而a[0],a[1]是一个一级指针
2.二级指针
级指针名就是二维数组名,一级指针名就是二维数组中的一维数组行名
- 指针数组及其应用
这个应用不说太多的叙述,直接看代码的运用:
二分查找:
- 指针做函数返回值及其注意
同上面的代码,使用指针作为函数参数返回多个函数值的实例:
在函数main()中调用函数month_day()时,将变量month和day的地址作为实参,在被调函数中用形参指针pmonth和pday分别接收地址,并改变了形参所指向变量的值。
1.2 本章学习体会
这章指针的学习还是有很多的缺漏点,因为在指针刚要学的时候,我的字符数组还没有学到位,然后学习指针就很匆忙,刚开始的时候也没有跟着林老师的步伐走,课堂派的预习作业也有点潦草的应付了事,没有很理解就去看同学的答案,自己并不是很理解。在这次指针的上机房考试的时候,我也不是很好的完成,因为这次考试有两题的原题,而且这两题都是我之前在PTA做过的,但是不是很理解,然后还有一题是在同学的博客看到的,刚好记了下来,才完成了三题的考试,其他的头绪一点都没有,我觉得在接下来的时间内,我要好好地复习好之前的内容,然后补缺补漏,不能遗漏自己的知识点。
感觉这两周的代码量,对于指针的代码还没有刷多少,然后数组的还有字符数组还没有刷完,所以目标仍有距离。
2.PTA实验作业
2.1 二分法查找
2.1.1 伪代码
先定义好函数Binsearch
int main()
{
定义数组a[N],i,key;
定义下标loc为-1,次数定义为0
输入n
开始使用循环输入,然后换行输入key
loc = BinSearch(a, n, key, &count)
printf("loc=%d,count=%d", loc, count)
}
int BinSearch(int *a, int n, int key, int *count)
{
定义left=0;right=n-1;中间值mid为0
while (left <= right)
定义mid=(left+right)/2;
执行(*count)++;
如果(key < a[mid])
{
right = mid - 1;
}
再如果 (key > a[mid])
{
left = mid + 1;
}
否则
{
返回 mid;
}
最后返回值为-1。
}
2.1.2 代码截图
2.1.3 总结本题的知识点
1.掌握利用二分法取中间值来做题
if (key < a[mid])
{
right = mid - 1;
}
else if (key > a[mid])
{
left = mid + 1;
}
2.注意在循环开始的时候正确利用指针来进行计算次数的累加
(*count)++;
2.1.4 PTA提交列表及说明
部分正确:是因为在计算的时候loc找到的位置是正确的,所以打出-1的时候是正确的,然后在下一步在VS调试中显示我的输出数据中的count也就是次数是错了,少了一次好像。然后我就在VS上面一直调试,一直更换(*count)++的位置,最后输出正确的值之后放到PTA上面就直接正确了
2.2 输出月份英文名
2.2.1 伪代码
先定义函数char *getmonth(int n)
int main()
{
定义 n;
char *s;
输入n;
s = getmonth(n);
if (s == NULL) 输出wrong input!
else 输出("%s\n", s);
return 0;
}
char *getmonth(int n)
{
switch (n)
{
case 1:返回 "January";
case 2:返回 "February";
case 3:返回 "March";
case 4:返回 "April";
case 5:返回 "May";
case 6:返回 "June";
case 7:返回 "July";
case 8:返回 "August";
case 9:返回 "September";
case 10:返回 "October";
case 11:返回 "November";
case 12:返回 "December";
default:返回 NULL;
}
}
2.2.2 代码截图
2.2.3 总结本题的知识点
1.考函数直接返回值,还有switch的运用
switch (n)
{
case 1:return "January";
case 2:return "February";
case 3:return "March";
case 4:return "April";
case 5:return "May";
case 6:return "June";
case 7:return "July";
case 8:return "August";
case 9:return "September";
case 10:return "October";
case 11:return "November";
case 12:return "December";
default:return NULL;
}
2.注意最后的default:return NULL,然后在主函数得出结果
2.2.4 PTA提交列表及说明
1.编译错误:第一次编译错误是因为返回月份的英文字母的时候,用的是‘’而不是“”,然后在VS上也不知道为什么“”会加下线,然后运行不了
2.部分正确:使用了switch之后,月份的输入有错误,所以后来改正了之后就正确了
2.3 字符串反正序连接
2.3.1 伪代码
先声明好函数fun(char *s, char *t);
主函数:
{
char s[100], t[100];
输入s
调用函数fun
printf("%s\n", t);
return 0;
}
void fun(char *s, char *t)
{
定义 k = strlen(s)来记录长度
定义j = 0;
for (int i = k - 1; i > -1; i--)
{
t[j] = s[i];
j++;
}
strcat(t, s);
}
2.3.2 代码截图
2.3.3 总结本题的知识点
1.掌握字符串长度的定义方法int k = strlen(s);
2.掌握反向的存储int j = 0;
for (int i = k - 1; i > -1; i--)
{
t[j] = s[i];
j++;
}
3.最后注意strcat(t, s);
2.3.4 PTA提交列表及说明
1.编译错误,刚开始我要写这一个strcat(t, s)可是在VS上不能运行,所以就放弃,就使用别的方法,然后还是不行,中间也出现编译的错误
2.答案错误,后来看到用了上面那个可以过,就开始改了,在for循环那个地方改了两次,改不正确,最后才发现要从大往小的走。
3.阅读代码
1.取了改段代码的一部分
int qmod(int a,int b,int c)
{
int res=1;
while(b)
{
if(b&1)
res=((LL)res*a)%c;
a=((LL)a*a)%c;
b>>=1;
}
return res;
}
对于这段代码,应该是灵活的运用了二级指针的方法;而我现在对于二级指针是很陌生的,所以改段代码很值得去学习
2.从整体看来,改段代码写的非常的简洁易懂,但是代码如果再加一些注释或许会更好
|
请发表评论