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