2

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分的没有本质上的差别,然后就过了!!!

3.阅读代码(-2--1分)

题目来源:ACM第39题
题目:

中文版:

 
乌托邦镇上有一群 n 面包师。
 这些面包师每个月都会举办一次庆祝活动,他们会把奖品颁发给那些幸运的面包师。
 这些幸运儿被选中如下: 一开始,一些面包师的房子上有粉笔的痕迹。 
每个面包师都有一份他 / 她最喜欢的面包师的名单。 
每次庆祝结束后,每位获奖者都会在他 / 她最喜欢的面包师的房子上画上粉笔记号。
 在每次庆祝活动之前,那些房子上粉笔记号奇数的面包师将被选为优胜者。 
由于将有一个伟大的奖品为第十三届庆祝活动的获胜者,你被要求找到它的获胜者的数字。
 
输入描述
输入的第一行包含一个整数 x (1每个实例的第一行包含两个整数 n (面包师的数量)和 t (我们想要的胜利者的庆典的数量)。
 11实例的下 n 行每行描述一个面包师。
 在每一行中,首先是面包师的名字(名字是不超过20个字符的小写字符串,没有空格) ,
然后是最初在面包师的房子上的粉笔记号
,然后是面包师最喜欢的名单上的面包师的数量,
接下来是面包师名单上的面包师的名字。
 
输出描述
每个测试用例应该有一行。
 对于每个测试用例,编写一行包含一个整数的代码,表示第 t 次庆祝活动的获胜者的数量。

代码:

代码解析:

首先,在代码第6行使用typedef为现有类型创建别名;
其次,在代码第8行可以看到我们即将要学的结构,结构类型为struct person,以变量定义的形式列出面包师的各信息项;
person p[MAXN]这段看不懂;
接着看主函数,用while循环做到循环输入面包师的各信息项;
在第78行使用getchar()吸收回车符;
使用初始化函数memset(),接着使用strcmp()函数将面包师名字进行对比。
这个代码比较简练,与老师所建议的排版基本吻合,值得借鉴;
再者,代码中适当使用string的库函数,提高代码的运算速率,在字符串对比部分使用strcmp()函数,这些都是值得学习的地方。
posted @ 2019-12-01 11:47  1911-林威  阅读(271)  评论(0编辑  收藏  举报
复制代码