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)的代碼行數和所用時間、博客字數和所用時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM