C程序第一次作业

1-1 计算两数的和与差

1 设计思路
(1)主要描述题目算法
第一步:利用指针psum接收sum的地址,指针pdiff接收diff的地址,因此 * psum为sum, * pdiff为diff。
第二步:对 * psum及 * pdiff进行赋值。
2.实验代码

void sum_diff( float op1, float op2, float *psum, float *pdiff )
{
  *psum = op1+op2;
  *pdiff = op1-op2;
}

1-2 拆分实数的整数与小数部分

1 设计思路
(1)主要描述题目算法
第一步:根据函数中形参指数型intpart为实参intpart的地址,fracpart也是如此,因此 * inpart的值为实参inpart的值,fracpart也是一样。
第二步: * inpart为x的整数部分,因此表示小数部分的 * fracpart=x- * inpart。
(2)流程图

2.实验代码


void splitfloat( float x, int *intpart, float *fracpart )
{
	float f;
	f = x; 
	*intpart = x*1;
	*fracpart = f-*intpart;
        return 0;
}

3.本题调试过程碰到问题及解决办法

错误原因:误使 * fracpart=f-(x/1),误记为浮点型数据与整型数据进行运算,最后结果为整型,正确应为浮点型。 改正方法:因 * intpart为整型数据,且为x的整数部分,因此直接用f- * intpart就可以。

2-1 在数组中查找指定元素

1 设计思路
(1)主要描述题目算法
第一步:定义k=-1,如果数组中有与x相等的元素时,另k等于其元素对应的下标。
第二步:遍历数组,为了找到最小下标,正向遍历数组,且当有一个对应元素时,即跳出循环。
第三步:返回k的值。
(2)流程图

2.实验代码

int search( int list[], int n, int x )
{
	int i = 0,k;
	k = -1;
	for(i = 0;i<n;i++) {
		if(list[i] == x) {
			k = i;
			break;
		}
	} 
	return (k);
} 

2-2 找最大值及其下标

1 设计思路
(1)主要描述题目算法
第一步:指针型a为a[0]的地址,b为最大值对应下标的p的地址。
第二步:令max=a[0],遍历数组。
第三步:若 (a+i)>max,则令max= * (a+i),b=i.
第四步:返回max的值。
(2)流程图

2.实验代码

int fun(int *a,int *b,int n)
{
	int max = *a;
	int i =0;
	for(i = 0;i<n;i++) {
		if(max < *(a+i)) {
			max = *(a+i);
			*b = i;
		}
	}
	return (max);
}


3.本题调试过程碰到问题及解决办法
错误原因:将 * b=a+i,a应当是a[0]的地址,因此不能将a+i。 改正方法:直接将 * b = i就可以。

3-1最小数放前最大数放后

1 设计思路
(1)主要描述题目算法
第一步:调用函数input(int *arr,int n),用for循环输入arr数组的值。
第二步:调用函数max_min(int *arr,int n),遍历数组,使得最大值位于函数元素的首位,最小值位于函数元素中的最后一位。
第三步:调用函数 output(int *arr,int n) ,遍历数组,按照格式输出arr数组中的元素。
(2)流程图
input函数流程图:

max_min函数流程图:

output函数流程图:

2.实验代码

void input(int *arr,int n)
{
   int i = 0;
   for(i = 0;i<n;i++) {
   	scanf("%d",&*(arr+i));
   }
   return 0;
} 
void max_min(int *arr,int n)
{
	int j = 0,max = *(arr+n-1),min = *(arr);
	int tmp1,tmp2;
	for(j=0;j<n;j++) {
		if(*(arr)>*(arr+j)) {
			tmp1 = *(arr);
			*(arr) = *(arr+j);
			*(arr+j) = tmp1;
		}
	}
	for(j=n-1;j>=0;j--) {
		if(*(arr+n-1)<*(arr+j)) {
			tmp2 = *(arr+n-1);
			*(arr+n-1) = *(arr+j);
			*(arr+j) = tmp2;
		}
	}
	return 0;
}
void output(int *arr,int n) {
    int k = 0;
    for(k=0;k<n-1;k++) {
    	printf("  %d",*(arr+k));
	}
	if(k == n-1) {
	  printf(" %d",*(arr+k)); 
	} 
	return 0;
}

3.本题调试过程碰到问题及解决办法

错误点1:输入的方式错误,写成 & arr++。解决方法:在查阅书籍以后,了解到输入指针型数组应用scanf("%d",&*(arr+i))。

3-2指针选择法排序

1 设计思路
(1)主要描述题目算法
第一步:调用函数sort(int *x,int n),x为a数组首元素的地址,n为10。
第二步:选择法排序,首先需要双层循环,外层循环,从大到小。
第三步:内层循环,控制比较的次数,决定是否交换位置。
(2)流程图
主函数:

sort函数:

2.实验代码

void sort(int *x,int n)
 {
 	int i = 0,j = 0;
 	int tmp;
 	for(i = 0;i<n;i++) {
 		for(j = i;j<n;j++) {
 			if(*(x+i)<*(x+j)) {
 				tmp = *(x+i);
 				*(x+i) = *(x+j);
 				*(x+j) = tmp;
			 }
		 }
	 }
	 return 0;
 }

3.本题调试过程碰到问题及解决办法

错误点1:将j=0,导致最后结果为从小到大输出,和题目要求的顺序正好相反。解决方法:在多次调试及翻书查阅后,意识到只要使j=i就好,i之前的排好的数不需要再重新再排。

4-1 判断回文字符串

1 设计思路
(1)主要描述题目算法
第一步:先运算输入的字符串中有多少个元素,用i来表示。
第二步:判断如果 * (s) != * (b-j-1),answer = 0,则输入的字符串不为回文字符串。
第三步:若*(s) 一直等于 *(b-j-1),,最后answer = 1,则输入的字符串为回文字符串。
第四步:返回answer得值,非0为真,0为假。
(2)流程图
主函数:

palindrome函数:

2.实验代码

bool palindrome( char *s )
{
  int i=0,j=0,answer=1;
  char *b = s;
  for(;*b != '\0';b++) {
  	i++;
  } 
  for(; *s != '\0';s++,j++) {
  	if(*(s) != *(b-j-1)) {
  		answer = 0;
	  }
  }
  	return (answer);
}  

4-2 使用函数实现字符串部分复制

1 设计思路
(1)主要描述题目算法
第一步:调用函数t,s指向主函数中的t,s。
第二步:将指针型t中的值赋值给另一个数组,计算出数组的长度,将m的大小与数组的长度用if语句来进行比较。
第三步:如果m大于数组得长度,则数组s直接输出为空数组;另一种则遍历数组,使数组s满足要求。
第四步:最后不要忘了,在if语句的最后写上*s='\0'。
(2)流程图
主函数:

strmcpy函数:

2.实验代码

void strmcpy( char *t, int m, char *s )
{
	int i = 0;
	char *b = t;
	for(;*b!='\0';b++) {
		i++;
	}
	if(m>i) {
	*s='\0';	
	} else {
		for(;*t!='\0';s++,t++)
	    *s = *(t+m-1);
	}
	*s = '\0';
 return 0;
}

3.本题调试过程碰到问题及解决办法

错误点1:并没有在最后加上*s = '\0',导致在最后提交时最后一个调试点错误。解决方法:在询问同学及参考了同学的代码后找出了自己的错误点,字符串的结尾应加'\0'. 错误点2:当m>i时,直接内容为空,导致最后的结果不为空字符。解决方法:在查阅书籍之后,发现内容应不为空,而为 * s='\0'。
额外加题3:为了防止信息被别人轻易盗取,需要把电码明文通过加密方式变换成为密文。变换规则如下:小写字母y变换为a,小写字母z变换为b,其他字母变换成为该字母ASCII码顺序后2为字幕,比如o变换成q。要求给出你的姓名全拼加密后的结果。
1 设计思路
(1)主要描述题目算法
第一步:想到用全局变量来定义N,及运用新学的指针来完成代码。
第二步:定义name[N],newName,并将name的首元素地址传给指针型newName。
第三步:遍历循环,用newName++来使newName循环指向下一个元素,分情况将newName中的元素进行替换,最后不要忘了使
newName = '\0'。
(2)流程图

2.实验代码

#include <stdio.h>
#define N 100 
int main ()
{
	char name[N],*newName;
	newName = name;
	scanf("%s",newName);
	int i=0;
	for(;*newName != '\0';newName++) {
		if(*newName  == 'y')
		{
			*newName  == 'a';
		} else if (*newName  == 'z') {
			*newName  == 'b';
		} else {
			*newName  = *newName  + 2;
		}
	}
	*newName  = '\0';
	printf("%s",name);
 } 

要求三、学习总结和进度

总结:在这两周我复习了数组,学习了指针的含义和概念,数组和指针以及字符串与指针,而对于字符串与数组的运用是最不熟练的,希望在写一次写博客总结时,自己可以写上对于字符串与数组的运用是已经完全掌握的,这是大的方面。
而在小的方面,在做PTA中的题目时,觉得自己对选择法排序的掌握已经退步为差不多为0,而选择法排序和冒泡法排序都是十分重要的,自己会尽快的去熟练掌握它们的。
pta第四次作业的第二题,自己印象是最深刻的,因为在这题自己也是一筹莫展,在网上查找完题目,提交了理解了以后就自己的代码,但因为自己最后的一点点不甘心,最后在同学的帮助下,还是用自己的思路完成了代码。而在此次分析网上的代码时,代码中可以有很多简化的地方,strlen(数组名)即为该数组的长度,不需要用for循环用i++来表示,书中和之前牛老师都有提到过,在以后自己也会使用这种方法的。
在总结的最后,分享一个应该掌握但有可能没有注意到的知识点:pta第三次作业的第二题中主函数的代码

#include<stdio.h>
void sort(int *x,int n);
int main ( )
{
 int *p,i,a[10];
 p=a;
 for (i=0;i<10;i++)  scanf("%d",p++);//为什么是输入p++ 
 p=a;//为什么没了它最后输出错误
 sort(a,10);
 for(i=0;i<10;i++)  printf("%4d",*p++);
 printf("\n");
 return 0;
 }

看到上面的代码时,我有两个问题:
(1)为什么输入的是p++,这个是简单的,因为p指向的是p首元素的地址,p++指向写一个元素的地址。
(2)为什么主函数中代码里先后有两个p=a,第一个p=a是将p指向a数组,那么第二个是什么意思,并且在将第二个p=a去掉以后,最后的输出结果是错误的?
在百度无果后(应该是自己输入的问题),翻看了C程序设计这本书,发现书上是给了明确的案例加解释的:原因是指针变量的初始值是a数组的首元素地址,但经过for循环后,p就指向了a数组的末尾(p是可变的),此时p的初始值已经不是a[0]的首地址了,而是指向a+10,因此若再执行p++时,p指向的是a数组的下面10个元素,而这些存储单元的值是不可预料的。内容在233页,希望可以帮到大家。
2、将PTA作业的源代码使用git提交到托管平台上,要求给出上传成功截图和你的git地址



git地址:(https://git.coding.net/exo07/disizhouzuoye.git)
3、点评3个同学的本周作业
于耀淞:(http://www.cnblogs.com/jsjyys/p/8589997.html)
周璇:(http://www.cnblogs.com/zhouxuan99/p/8597350.html)
丰大为:(http://www.cnblogs.com/DavidPark/p/8551402.html)
4、请用表格和折线图呈现你本周(3/12 8:00~3/26 8:00)的代码行数和所用时间、博客字数和所用时间

posted @ 2018-03-19 20:50  董雅洁  阅读(429)  评论(16编辑  收藏  举报