1.本章学习总结(2分)
1.1 学习内容总结
1.指针与数组
数组:数组是用于储存多个相同类型数据的集合。
指针:指针是用来存放内存地址的变量。
定义指针的一般形式为
类型名 * 指针变量名;(指针声明符*,在定义指针变量时使用,说明被定义的那个变量是指针)
下面是一些指针定义的例子:
int *p;/*定义一个指针变量p, 指向整型变量*/
char * cp;/*定义一个指针变量cp, 指向字符型变量*/
float *fp;/*定义一个指针变量fp, 指向实型变量*/
double *dp2;/*定义一个指针变量dp2, 指向双精度实型变量*/
注意:不同类型指针变量所占的内存空间的大小都是相同的。
指针被定义后,必须将指针变量和一个特定的变量进行关联后才可以使用它
下面的语句可以对指针变量p赋值:
int i, *p;
p=&i;
p=0;
p=NULL;
指针的基本运算:
int *p, a=3;
p=&a;
用运算符&取变量a的地址,并将这个地址值作为指针p的值,使指针p指向变量a。
int a=1, x, *p;
p=&a;
x=*p++;
指针p先指向a,其后的语句x=* p++;将p所指的变量a的值赋值给变量x,然后修改指针的值,使得指针p不再指向变量a。
再如表达式
*p=*p+1;
++ *p;
(*p)++;
都是将指针p所指的值加1.
指针的赋值运算:
int a=3, *p1, *p2;
p1=&a;
p2=p1;
将变量a的地址赋给指针p1,再将p1的值赋给指针p2,因此指针p1和指针p2都指向变量a。
注意:指针变量在定义后也要先赋值再引用。
2.字符指针
字符指针:指存放字符串首字符的地址的指针。
字符数组与字符指针都可以处理字符串,但两者有重要区别。
char sa []="This is a string";
char * sp ="This is a string";
字符数组sa在内存中占用了一块连续的单元,有确定的地址,每个数组元素放字符串的一个字符,字符串就存放在数组中。字符指针sp只占用一个可以存放地址的内存
单元,存储字符串首字符的地址,而不是将字符串放到字符指针变量中去。
常用的字符串处理函数
scanf ("%s", s);/*假设s为字符数组名*/
该函数遇到回车或空格输入结束,并自动将输入的数据和字符串结束符'\0'送入数组中
get (s);/*假设s为字符数组名*/
函数遇回车输入结束,自动将输入的数据和'\0'送入数组中.采用gets()输入的字符允许带空格.
fgets(str, 7, stdin); 原型为:
# include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
fgets() 虽然比 gets() 安全,但安全是要付出代价的,代价就是它的使用比 gets() 要麻烦一点,有三个参数。它的功能是从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。它的返回值是一个指针,指向字符串中第一个字符的地址。
strcat(s,t)
把字符串t连接到s,是s成为包含s和t的结果串
strcmp(s,t)
逐个比较字符串s和t中的对应字符,直到对应字符不等或比较到串尾
strcpy(s,t)
把字符串t复制到s中
strlen(s)
计算字符串s的长度(不包括'\0')
3.二级指针、行指针
二级指针:指向指针的指针。
其一般定义:
类型名 * * 变量名
概念图:
行指针:定义:指向由m个元素组成的一维数组的行指针变量
行数组指针举例:
int (p)[4];
它表示,数组p有4个int型元素,分别为(p)[0]、(p)[1]、(p)[2]、(p)[3] ,亦即p指向的是有4个int型元素的一维数组,即p为行指针
4.指针数组综合运用
数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活。
其更灵活的地方表现在2点。
1.当指针数组与函数综合应用时,函数可以返回多个值。
2.可以为指针申请动态空间,不浪费内存。
1.2 本章学习体会
学习感受:在本章的学习内容中,我确实感受到了“指针是c的灵魂”,因为指针不仅灵活,而且有些时候会方便点,但是就是太难学会了。至今,我感觉自己对指针的了解还不够透彻。最近好像也不怎么打王者荣耀了,所有在学习c语言的时间相应多了,希望可以学好点。
代码量:550
2.PTA实验作业(7分)
2.1 7-1(指针做函数返回值) 查找指定字符 (15 分)
2.1.1 伪代码
main函数
定义类型为char的search函数(形参为字符型指针a,字符ch)
定义字符型数据ch
定义字符数组a[100]
定义字符指针index
输入待查找字符
getchar()吸收回车符
输入非空字符串
index等于search(a,ch)的返回值
if index等于NULL then
输出Not Found
else
输出index-a的结果
end if
类型为char的search函数(形参为字符型指针a,字符ch)
定义字符指针q
将q初始化
定义整型数据i=0
while a[i]不等于0 then
if a[i]等于待查找字符 then
q等于a[i]的地址
i自增
end if
返回q
2.1.2 代码截图
2.1.3 总结本题的知识点
1.巧妙地通过函数返回指针,并且将2个指针相减来得到字符的下标
2.正确判断使用哪一种输入语句:使用scanf语句时,遇到空格停止。使用fgets,gets函数输入时,遇到回车停止。
3.通过循环来查找是否有待查找字符
2.1.4 PTA提交列表及说明
多种错误:循环条件设置错误,导致死循环,然后运行超时。
部分正确:循环条件设置依旧有问题,当待查找字符在主字符串存在时,可准确查找,但是当待查找字符不存在主字符串时,却输出下标等于200多,300多。
部分正确:输入字符串语句选择scanf,导致含空格的测试点过不了。
2.2 7-5 删除字符串中的子串 (20 分)
2.2.1 伪代码
main 函数
定义类型为void的detel函数(形参为字符指针p,字符指针q)
定义字符数组a,数组b
定义字符变量length_b, length_a
分别输入字符串和字串
令length_b等于数组b的长度
while 在主串中寻找到字串的位置 then
length_a等于数组a的长度
调用detel函数
end while
输出字符数组a
detel函数(形参为字符指针p,字符指针q)
p等于子串在主串中的位置
while *(p+length_b)!='\0' then
从p位置后的字符向length_b个长度往前覆盖
end while
*p=*(p+length_b);
2.2.2 代码截图
2.2.3 总结本题的知识点
1.通过strstr函数来确定字串的有无和位置
2.使用循环结构进行字符数组从特定位置往前一定长度挪动,实现覆盖,以致于达到删除子串的目的
3.指针与函数的综合应用
2.2.4 PTA提交列表及说明
这道题老师上课讲过,还有pta一次过。但是我为什么放在博客上呢。因为虽然在课上听过,但是我一写下去,感觉完全自己写了一遍,忘了老师课上讲的内容了。课上听课的效率极低。
2.3 6-9 合并两个有序数组(2) (15 分)
2.3.1伪代码
merge函数
定义整形数据i作为循环变量
定义整形数据j,k分别作为数组a,数组b的下标
开辟一个临时指针,并申请动态空间
for i = j = k = 0 to 一个数组的最后一个元素 then
if 数组a的元素小于数组b的元素 then
将数组a的元素存入temp
将此数组a的元素的下标自增
else
将数组b的元素存入temp
将此数组b的元素的下标自增
end if
end for
while 数组a的元素还未到最后一个 then
将数组a后面的元素存入temp
end while
while 数组b的元素还未到最后一个 then
将数组b后面的元素存入temp
end while
释放临时指针temp
2.3.2代码截图
2.3.3 总结本题的知识点
1.开辟指针temp,申请动态空间,有效节省了内存
2.当数据量庞大,循环次数多时,用if-else比用if-if效率更高
2.3.4 PTA提交列表及说明
多种错误:运行超时+答案错误,运行超时是因为我一开始采用的方法要2次循环。
部分正确:因为其中一个测试点数组长度为0的过了,但是其实代码是错了,瞎猫撞上死耗子
3.阅读代码(-2--1分)
选这道题时,是因为对strstr函数实现有点兴趣,可是看完代码,发现这其实跟pta上查找子串的主要原理差不多。
但是这此题代码,我发现它的命名很规范,而且函数与指针的综合使用很自然。