C博客作业05--2019-指针
0.展示PTA总分(0—-2)
1.本章学习总结(2分)
1.1 学习内容总结
指针做循环变量做法:例如:
for (p = a; p <= a + 9; p++)//使用指针求和
{
sum = sum + *p;
}
详情见课本195 例8-7
字符指针如何表示字符串:例如:
char sa[] = "array";
char* sp = "point";
printf("%s", sa);//数组名sa作为printf的输出参数
printf("%s", sp);//字符指针sp作为printf的输出参数
printf("%s\n", "string");//字符串常量作为printf的输出参数
详细见课本201 8.4.2字符串和字符指针
动态内存分配:
动态分配内存的方式有两种:
1.动态存储分配函数malloc()
函数原型:void*malloc(unsigned size)
实现方式,例:
//动态分配n个整数类型大小的空间
if ((p = (int*)malloc(n * sizeof(int))) == NULL)
{
printf("Not able to allocate memory.\n");
exit(1);
}
每次动态分配都必须检查是否成功。
2.计数动态存储分配函数calloc()
函数原型:void * calloc(unsigned n, unsigned size)
实现方式,例:
//为数组p动态分配n个整数类型大小的空间
if ((p = (int*)calloc(n, sizeof(int))) == NULL)
{
printf("Not able to allocate memory.\n");
exit(1);
}
malloc()与calloc()的最大区别:malloc()对所分配的存储块不做任何事情,calloc()对整个区域进行初始化
附加:
动态存储释放函数free()
函数原型:void free (void *ptr)
功能:释放由动态存储分配函数申请到的整块内存空间
注:释放后,不能再使用该指针
分配调整函数realloc()
函数原型:void *realloc(void *ptr,unsigned size)
功能:更改以前的存储分配
指针数组及其应用
指针数组的概念:数组的各个元素都是指针类型,用于存放内存地址
一维指针数组的格式:
类型名* 数组名[数组长度];
例:
int a[10];
char* color[5];
可用语句:
printf("%s\n", color[i]);
表示输出color[i]所指向的字符串;
使用语句:
char* tmp;
tmp = color[0];
color[0] = color[4];
color[4] = tmp;
来实现两个数之间的交换;
指针数组是由指针变量构成的数组,在操作时,既可直接对数组元素进行赋值(地址值)和引用,
也可以间接访问数组元素所指向的单元内容,改变或引用该单元的内容。
二级指针、行指针
二级指针(指向指针的指针)定义格式:
类型名** 变量名;
例:
int a = 10;
int* p = &a;
int** p = &p;
a、* p、** p代表同一个单元,它们的值相同
理论上,可以定义任意多级指针,但实际中很少超过二级,避免指针级数过多造成理解错误,使程序可读性降低。
补:
二维数组的指针形式:
由a[i]等价于* (a + i)可得,a[i][j]等价于* (*(a + i) + j),也可表示成* (a[i] + j);
行指针:int(*p)[n]; p = a;
p + i表示第i行的首地址a[i],二级指针
a[i][j] = *(*(p + i) + j) = (*(p + i))[j] = p[i][j];
补:
列指针:int* p; p = a[0];
*(p+i),表示离a[0][0]第i个位置的元素
函数返回值为指针
返回指针的函数一般都返回全局数据对象或主调函数中数据对象的地址
因为所有的局部数据对象在函数返回时就会消亡,其值不再有效
例:
课本11-8的改写
char* match()
{
char ch, str[80], * s = str;//定义局部字符数组
printf("Please Input the string:\n");//输入
scanf("%s", str);
getchar();
ch = getchar();
while (*s != 0)
if (*s == ch)
return s;//返回局部字符数组地址
else
s++;
return(NULL);
}
运行该程序,将会得到错误的输出结果
1.2 本章学习体会
学习感受:无论是数组还是指针都是循环的一种使用形式,循环部分仍需加强;
代码量:950,未达标
2.PTA实验作业(7分)
2.1 题目名1:6-6 查找子串
2.1.1 伪代码
定义len1,len2用来表示*s,*t的长度
while(i,j均没有超过各自的上限)
{
if(两者相等)
{
均移至下一位
}
else
{
*s移至下一位
*t返回首位
}
}
if(j大于等于len2)
return 找到的首地址
else
return NULL
2.1.2 代码截图
2.1.3 总结本题的知识点
1.
查找子串的方法
用while或者for循环对主串和子串逐一查找
if(找到一位相同)
{
继续往下比对
}
else
{
当前所找到的主串的部分与子串不完全相同
主串后移
子串回到首地址
}
2.
对于指针的返回值
返回两个量只差的首地址(&s[i-j])
2.1.4 PTA提交列表及说明
三次的部分正确(6分):问题在于,对找到的子串在主串中的首地址的返回值,只是单纯地返回&s[i],后来再查找老师的课件后,把返回值改对了;
段错误:在while循环中,没注意到什么时候在条件i<len1处,多大了一个“=”,导致越界;
部分正确(18分):在最终返回s的首地址的判断条件(j>=len2)中没有考虑到取等的情况;
答案正确:。。。
2.2 题目名2:6-10 填充矩阵
2.2.1 伪代码
定义i,j
for(i初值为0;i最值为n-1;i++)
{
for(j初值为0;j最值为n - 1;j++)
{
if(i+j=n-1)//斜对角线
{
为1
}
else if//斜对角线上方
{
为3
}
else//斜对角线下方
{
为2
}
}
}
2.2.2 代码截图
2.2.3 总结本题的知识点
通过for循环填充矩阵
选这题跟难度无关,主要是要提醒自己要看清题目,认真看原代码
容易出现:认为原代码没有输出的现象,然后在函数中输出,导致越界的情况
2.2.4 PTA提交列表及说明
编辑错误:在搬代码的时候把全部代码都复制到pta,导致编辑错误
答案错误:以为原代码中没有输出,然后,就在函数中输出,之后就出现这种情况
2.3 题目名3:7-1(指针做函数返回值) 查找指定字符
2.3.1 伪代码
定义len为读入字符串的长度,index初值为 - 1(只要小于0都可以)
读入需要查找的字符ch
读入字符串
for (i = 0; i < len, i++)
{
if (找到)
{
index=i;
}
}
if index不等于初值
输出找到的i
else
输出Not Found
2.3.2 代码截图
2.3.3 总结本题的知识点
1.
通过for循环找到下标
然后输出
2.
在输入时scanf()中要加上"\n"不然无法读入字符串
3.
对于index的定义初值,不能大于等于0,否者容易出现输出时,即使没有找到某个下标,也会输出那个下标的情况
2.3.4 PTA提交列表及说明
两次编辑错误:vs中的gets_s()到pta中为改成gets()
部分正确(13分):在于第3个测试点(index = max,字符串中有空格)这个点过不去;
部分正确(2分):为了专门过第3个测试点,在试代码,但是,依旧没过;
答案正确:不知道为什么,代码跟之前的13分的没有本质上的差别,然后就过了!!!