1. 程式人生 > 實用技巧 >實驗三:磕磕碰碰

實驗三:磕磕碰碰

實驗內容

1.實驗任務1

#include<math.h>
#include<stdio.h>

int main(){
    float a,b,c,x1,x2;
    float delta,real,image;
    
    printf("Enter a,b,c:  ");
    
    while(scanf("%f,%f,%f",&a,&b,&c)!=EOF){
        if(a==0)
        printf("not quadratic equation.\n\n");
        else{
            delta
=b*b-4*a*c; if(delta>=0){ x1=(-b+sqrt(delta))/(2*a); x2=(-b-sqrt(delta))/(2*a); printf("x1=%.2f,x2=%.2f\n",x1,x2); } else{ real=-b/(2*a); image=sqrt(-delta)/(2*a); printf(
"x1=%.2f+%.2fi,x2=%2f-%2fi\n\n",real,image,real,image); } } printf("Enter a,b,c: "); } return 0; }

執行結果

但是我偶然發現在先輸入部分數字之後再按Ctrl+Z會出現無限輸出的情況

後來瞭解到這是因為......

可能這就是所謂的“漏洞”吧。

Ps:EOF的值一般是-1

在我們進行包括scanf等的輸入函式使用時,其實使用者在cmd中的輸入實際是存放於緩衝區當中,當用戶鍵入回車那一瞬間,之前輸入的資料才會被存進去,而這裡無論是單個字元還是字串,我們都知道scanf的返回值呢是表示成功接受到的物件的個數,那這裡如果遇到特殊情況,比如緩衝區檔案流滿等問題,那麼scanf將如何處理呢?答案是返回-1 ! 這裡不光是scanf,返回值為個數的函式,遇到檔案流滿大多都會返回-1,所以這個-1用的比較多,那麼stdio.h就索性專門定義一個巨集來表示,取End Of File(檔案末尾的意思)的前三個字母即組成EOF,所以也就有了 #define EOF (-1) 這樣的話!

2.實驗任務2

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 5

int main(){
    int x,n;
    
    srand(time(0));
    n=0;
    do{
        n++;
        x=rand()%10;
        printf("%3d",x);
        
    }while(n<N);
    
    printf("\n");
    
    return 0;
}

執行結果

PS:

偽隨機數:

偽隨機數是用確定性的演算法計算出來自[0,1]均勻分佈的隨機數序列。並不真正的隨機,但具有類似於隨機數的統計特徵,如均勻性、獨立性等。在計算偽隨機數時,若使用的初值(種子)不變,那麼偽隨機數的數序也不變。偽隨機數可以用計算機大量生成,在模擬研究中為了提高模擬效率,一般採用偽隨機數代替真正的隨機數。模擬中使用的一般是迴圈週期極長並能通過隨機數檢驗的偽隨機數,以保證計算結果的隨機性。

so~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

3.實驗任務3

#include<stdio.h>
#include<math.h>

int main()
{
    int m,k,n;
    
    k=0;

    for(n=101;n<=200;n++)
    {
        for(m=2;m<=sqrt(n);++m)
         if(n%m==0)break;
        if(m>sqrt(n))
        {
            printf("%d\t",n);
            k++;
            if(k%5==0)
            printf("\n");
            
        }
    }
    printf("101~200");
    
    
    printf("101^200之間共有%d個素數",k);
    
 
    

  return 0;}

執行結果(正常)

而在這之前又出現了一些bug......

and......

4.實驗任務4

#include<stdio.h>

int main() {

    int a,s,t,m;

    m = 1;

    t = 0;

    

    printf("Enter a number: ");

    while (scanf("%d", &s) != EOF) {



        while (s >= 1)

        {

            a = s % 10;

            s = s / 10;

            if (a % 2 != 0)

            {

                t = t + a * m;

                m = m * 10;

            }

        }

        if (s % 2 == 1)

            t = t + m * s;

        printf("new number is %d\n", t);

        printf("Enter a number: ");

        t = 0;

        m = 1;

    }

    return 0;

}

執行結果(肯定正常了,不用看了啦~~~~~~~~~~~~~~~~~~~~~)

但其實不是,我發現這個程式執行存在異常

其實就是資料型別的範圍問題啦~~

PS:演算法思路

其實就是先輸入一個數,然後用對10取餘的迴圈語句的方式得出各個數位上的數字,再將這些數字對2取餘,若為1則判定為奇數,再次用迴圈語句將這些資料按原來的順序依次輸出,但輸出的卻是真的數,這依靠於輸出的變數乘以相應的位數再加上之前這種迴圈所得出的結果。

5.實驗任務5

#include<stdio.h>
int main(){
    int n,k,i;
    float s,x;
    s=0;
    x=1;
    i=1;
    k=1;
    printf("Enter n(0^10):");
    
    while(scanf("%d",&n)!=EOF){
        for(; k<=n; k++)
        {
            i=(-1)*i*k;
            s=s-x/i;}
            printf("n=%d,s=%f\n\n",i,s);
            
            printf("Enter n(0^10):");
    }
        
    
    return 0;
    
    
}

就因為一個引號害我弄了半天還以為電腦該換了(> )3:<)

while(scanf("%d,&n")!=EOF){

emmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

and 來之不易的執行成果:



6.實驗任務六
#include<stdlib.h>
#include<time.h>
int main(){
    int n,i,t;
    srand(time(0));
    t=rand()%30+1;
    i=0;
    printf("猜猜2020年哪一天會是你的luck day\n");

    printf ("開始嘍,你有三次機會,猜吧(1^31):");
    scanf("%d",&n) ;
    while(i<=3){
        if(n>t){
    
        printf("你猜的日期晚了,luck day悄悄溜到前面啦\n");
        printf("再猜:");
        scanf("%d",&n) ;
        i++;}
        else if(n<t){
        
        printf("你猜的日期早了,luck day還沒到呢\n");
        printf("再猜;");
        scanf("%d",&n);
        i++;}
        else
        printf("猜中了,nice!") ;
        i++;
        }
        printf("次數用完啦。偷偷告訴你:12月,你的luck day是%d號",t); 
        return 0; 
         
        
         
    }
    
    

執行結果一切正常

運氣真好~
再猜億遍~~



實驗總結

這次的實驗很有難度呢,而且還有很多有新的概念呢~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

比如說:

1.偽隨機數rand()和srand()
偽隨機數是用確定性的演算法計算出來自[0,1]均勻分佈的隨機數序列。並不真正的隨機,但具有類似於隨機數的統計特徵,如均勻性、獨立性等。在計算偽隨機數時,若使用的初值(種子)不變,那麼偽隨機數的數序也不變。偽隨機數可以用計算機大量生成,在模擬研究中為了提高模擬效率,一般採用偽隨機數代替真正的隨機數。模擬中使用的一般是迴圈週期極長並能通過隨機數檢驗的偽隨機數,以保證計算結果的隨機性。

在標準的C庫中函式rand()可以生成0~RAND_MAX之間的一個隨機數,其中RAND_MAX 是stdlib.h 中定義的一個整數,它與系統有關。

rand()函式沒有輸入引數,直接通過表示式rand()來引用;例如可以用下面的語句來列印兩個隨機數:

printf("Random numbers are: %i %i\n",rand(),rand());

因為rand()函式是按指定的順序來產生整數,因此每次執行上面的語句都列印相同的兩個值,所以說C語言的隨機並不是真正意義上的隨機,有時候也叫偽隨機數。

為了使程式在每次執行時都能生成一個新序列的隨機值,我們通常通過為隨機數生成器提供一粒新的隨機種子。函式 srand()(來自stdlib.h)可以為隨機數生成器播散種子。只要種子不同rand()函式就會產生不同的隨機數序列。srand()稱為隨機數生成器的初始化器。

2.標頭檔案time.h和time(x)

函式名稱: localtime

函式原型: struct tm *localtime(const time_t *timer)

函式功能: 返回一個以tm結構表達的機器時間資訊

函式返回: 以tm結構表達的時間

timer-使用time()函式獲得的機器時間

當然還有正確的開啟方式!

1.迴圈語句的巢狀使用

*特別注意""和括號的使用!兩個看似相同的程式可能因為一個小小的疏忽而天差地別!

2.變數的引入

*不要混淆各個變數!

3.實驗之間的遷移與運用

*一個實驗可能包含在另一個實驗之中,理解運用好基礎實驗才能handle更復雜的實驗!

4.學會簡化程式

*儘量使問題簡單化!

再次謝謝所有看到最後的人!