天天看點

寒假作業3

合作者:周政演 031602543 部落格連結魏璐炜 031602136 部落格連結

相同部分

大緻設計思路

根據讨論 制定了兩種思路:

  1. 将數字與運算符建立映射,利用随機數函數在運算符位置上模拟出四種運算符,舍棄除數為0的情況以及輸出不為整數的情況。
  2. 将各種情況讨論出來,再一一編碼。

編碼規範

因為想到自己制訂的編碼規範未必規範,是以上網查找了一些編碼規範,經過篩選,共同學習後制訂出了編碼規範。

一、排版:1、關鍵詞和操作符之間加适當的空格。

  2.相對獨立的程式塊與塊之間加空行

  3.較長的語句、表達式等要分成多行書寫。

  4.劃分出的新行要進行适應的縮進,使排版整齊,語句可讀。

  5.長表達式要在低優先級操作符處劃分新行,操作符放在新行之首。

二、注釋

1.注釋要簡單明了。

  2.邊寫代碼邊注釋,修改代碼同時修改相應的注釋,以保證注釋與代碼的一緻性。

  3.在必要的地方注釋,注釋量要适中。注釋的内容要清楚、明了,含義準确,防止

  注釋二義性。保持注釋與其描述的代碼相鄰,即注釋的就近原則。

  4.對代碼的注釋應放在其上方相鄰位置,不可放在下面。

  5.變量、常量的注釋應放在其上方相鄰位置或右方。

三、命名

1.較短的單詞可通過去掉“元音”形成縮寫;

  2.較長的單詞可取單詞的頭幾發符的優先級,并用括号明确表達式的操作順序,避

  免使用預設優先級。

四、可讀性

1.避免使用不易了解的數字,用有意義的辨別來替代。

  2.不要使用難懂的技巧性很高的語句。

  3.源程式中關系較為緊密的代碼應盡可能相鄰。

五、變量

1.去掉沒必要的公共變量。

  2.構造僅有一個子產品或函數可以修改、建立,而其餘有關子產品或函數隻通路的公共

  變量,防止多個不同子產品或函數都可以修改、建立同一公共變量的現象。

  3.仔細定義并明确公共變量的含義、作用、取值範圍及公共變量間的關系。

  4.明确公共變量與操作此公共變量的函數或過程的關系,如通路、修改及建立等。

 

六、函數、過程

  1.一個函數最好僅完成一件功能。

  2.為簡單功能編寫函數。

  3.函數的功能應該是可以預測的,也就是隻要輸入資料相同就應産生同樣的輸出。

  4.盡量不要編寫依賴于其他函數内部實作的函數。

  5.檢查函數所有參數輸入的有效性。

八、程式效率

1.程式設計時要經常注意代碼的效率。

  2.在保證軟體系統的正确性、穩定性、可讀性及可測性的前提下,提高代碼效率。

  3.不能一味地追求代碼效率,而對軟體的正确性、穩定性、可讀性及可測性造成影

  響。

  4.程式設計時,要随時留心代碼效率;優化代碼時,要考慮周全。

  5.在多重循環中,應将最忙的循環放在最内層。

  

程式一的實作與結果測試

函數頭

#include<stdio.h> 

#include<stdlib.h>

#include<time.h>

#include<stdbool.h>

int get_integer(void);//擷取題目數 

void get_number(int *pa,int *pb,int *pc);//擷取數字 

char get_sign(void);//擷取運算符号 

int value(int,int,char); //求兩個數四則運算的值 

bool language=true;
           

在程式中有五個自定義函數,建立這麼多的自定義函數的目的是簡化main函數,将函數分成許多小的功能,各個函數的功能在代碼中均有注釋。

雙語界面

寒假作業3

這次程式的操作是

擷取題目數

int get_integer(void) 
{
	int n,num;
	char ch;
	bool judge=true;
	if(language) printf("請輸入0~10的整數題數:\n");
	else printf("Please enter 0~10 integer question.");
	n=scanf("%d",&num);
	
	if(num>10||num<1)//限定為0~10的題目數 
	judge=false;
	
	while(n!=1||judge==false)//給使用者再次嘗試的機會 
	{
		if(language) printf("請輸入一個0~10整數,如2,3.\n");
		else printf("Please enter 0~10 interger,such as 2,3.\n");
		while((ch=getchar())!='\n')
		   continue;
		n=scanf("%d",&num); 
		if(num>10||num<1)
		judge=false;
		else
		judge=true;
	} 
	return num;
}
           

該段代碼的作用是擷取題目數,其中代碼排除了0~10以外的題數以及非整數的輸入。循環語句中運用了最近學習的一個小技巧:若是擷取是如ndsjfbs這樣的一段輸入,循環語句會給使用者一次提示并給予他們重新輸入的機會,同時将使用者的錯誤輸入清空。

提供重新輸入的機會

寒假作業3

擷取随機數

void get_number(int *pa,int *pb,int *pc)//擷取随機的數字 
{
	srand(time(NULL));
	*pa=rand()%11;
	*pb=rand()%11;
	*pc=rand()%11;
}
           

其中srand()rand()來自頭檔案stdlib.h,time()來自頭檔案time.h。srand()用來初始化rand(),而srand()中的time(NULL)是用時間作為參數,使種子不斷變化,進而産生不同的“随機數”。

rand()函數傳回一個整數值,此時将這個整數值用11取餘,就可以得到範圍是0~10的數。

擷取符号

char get_sign(void)//将運算符對應于數字,用随機數模拟随機運算符 
{
	char sign;
	int int_sign;
	srand(time(NULL));
	int_sign=rand()%4+1;
	switch(int_sign)
	{
		case 1:sign='+';break;
		case 2:sign='-';break;
		case 3:sign='*';break;
		case 4:sign='/';break;
    }
	return sign;
}
           

在該自定義函數中,建立了一個數字到運算符号的映射,1、2、3、4對應着字元+、-、*、/。産生一次随機數便能傳回一個運算符,模拟随機産生運算符的功能。

計算二進制表達式的值

int value(int a,int b,char sign)//計算兩個數的四則運算 
{
	int v;
	switch(sign)//注意除數不能為0,整數輸出 
	{
		case '+':v=a+b;break;
		case '-':v=a-b;break;
		case '*':v=a*b;break;
		case '/':v=a/b;break;
	}
		return v; 
}
           

本次作業隻輸出3個數字的題目,若是一一讨論,将大大增加程式的複雜程度,于是化整為零,編寫出兩個數的運算函數,這樣增加了程式的可讀性和可移植性,若是要增加到4個數字、5個數字的混合運算,隻需在main函數中稍作更改即可。

主函數

int main(void)
{
	int i,num,count=0;//num為題數,count用于計算題數 
	int a,b,c,answer;//abc為計算的數字,answer是使用者輸入的答案 
	int * pa,* pb,* pc; 
	pa=&a;pb=&b;pc=&c;//用于擷取數字的函數 
	char sign1,sign2;
	char ch;
	printf("選擇中文版請輸入1。\nEnter 0 to choose English.");
    scanf("%d",&language);
	
    num=get_integer();
    if(language)
    printf("請輸入一個整數答案(輸入e結束并得出結果)\n"); 
    else printf("Please enter an integer answer(e to quit and get the result).\n");
	for(i=1;i<=num;)//自增符号放于檔案尾,防止用continue剔除不合要求題目時減少了循環次數 
    {
    	sign1=get_sign();
        sign2=get_sign();
	    get_number(pa,pb,pc);
		if(sign2=='/')//剔除除數為0和答案不為整數的題目 
		    if(c==0||(float)(b/c)==(b/c))continue;
		
		if(sign1=='/')//剔除除數為0和答案不為整數的題目 
		    if(value(b,c,sign1)==0||(float)(b/c)==(b/c))continue;
		
		printf(" %d %c ( %d %c %d)=",a,sign1,b,sign2,c);	
		if(scanf("%d",&answer)!=1)break;//擷取使用者的答案,輸入e時退出 
		b=value(b,c,sign2);
		
		if(answer==value(a,b,sign1))
		{
			if(language)
			printf("答案正确!\n");
			else printf("You're right!\n");
			count++;
		}
		else {
		if(language)printf("答案錯誤!答案為%d\n",value(a,b,sign1));
	    else printf("It's wrong,the right answer is %d\n",value(a,b,sign1));
		}
		i++;
	}
	if(language)printf("正确題數:%d",count);
	else printf("You have %d right answer.",count);
	return 0;
}
           

主函數中的循環語句中有多個條件語句,用與剔除各種不符合要求的題目輸出。

完整代碼

測試結果

寒假作業3

不足之處

檔案的運作速度過慢,有時要等待數秒才能輸出題目,我們認為原因如下:

  1. 剔除不符合要求的輸出的條件語句太多,導緻重複的運作過多。
  2. 随機數的産生是以時間為種子,短時間内系統輸出時間是不變的,是以會産生相同的随機數,這樣這些相同的随機數都會被剔除,直到一個時刻産生符合要求的随機數為止。

分工與合作

寒假作業3
寒假作業3
寒假作業3
寒假作業3
寒假作業3
寒假作業3
寒假作業3
寒假作業3
寒假作業3

github的送出連結

https://github.com/Vancasola/cooperation

差異部分

合作過程以及體會

  • 接到題目後,兩個人很快組成一個小組,對題目進行讨論。開始時先讨論清楚題意,然後分享各自的思路,二人綜合之後,決定采用如下思路:将數字與運算符建立映射,利用随機數函數在運算符位置上模拟出四種運算符,舍棄除數為0的情況以及輸出不為整數的情況。031602543先打出主函數的結構,經過讨論後定下子產品,查找資料學習随機數的原理以及使用。由031602543編寫擷取題數、求兩數四則運算函數值、擷取符号的函數,由031602136編寫随機數函數。因為這次作業并不是很難,是以二人隻在git上送出了幾次就把程式寫完了,若是在更大的項目上合作,恐怕需要花費的時間和精力就多得多了,送出和更改的次數也會增加許多。兩個人在編碼的時候,都是使用多組測試資料,将代碼盡量檢查到沒有錯誤,才push上去,這樣減少了對方的工作量。
  • 在學習git時遇到了許多問題,其中,在push代碼到倉庫時,總是顯示沒有權限,網絡上普遍的說法時缺少ssh key,需要将sshkey添加到github中的setting裡,嘗試多次後,發現并不奏效,後來向助教學長請教了一下,發現是并未将成員添加到倉庫裡面,這是教程裡面沒有提到的,将成員添加後,就順利地解決了這個問題。

分工

  • 031602543 主要負責編碼、調試程式、解決git中遇到的問題、完成随筆。
  • 031602136 主要負責界面美化、翻譯、記錄過程。
  • 分工github位址

031602543附:

程式二的嘗試(隻嘗試核心思路)

分數的嘗試