算法筆記——C/C++語言基礎篇(已完結)

 

開始系統學習算法,但願本身可以堅持下去,期間會把經常使用到的算法寫進此博客,便於之後複習,同時但願可以給初學者提供必定的幫助,手敲不免存在錯誤,歡迎評論指正,共同窗習。博客也可能會引用別人寫的代碼,若有引用,定會註明。本博客內容主要按照算法筆記內容進行學習。(2018-12-03)php

1.萬能頭文件html

#include<bits/stdc++.h>
using namespace std;
int main(){
  
  ...
  
  return 0;
}

2.判斷素數ios

int IsPrime(int n){
    for(int i=2;i<=sqrt(n+1);i++){
        if(n%i==0){
            return 0;
        }    
    }
    return 1;     
}
//返回0表明不是素數,返回1表明是素數    

 3.求一元二次方程的根c++

題目連接(點擊進入)程序員

數學內容:算法

輸出格式:數組

補充:%0md(m表明寬度,右對齊),當變量不足m位時,將在前面補0,例如a=123,%05d,則輸出結果爲00123數據結構

#include<stdio.h>
#include<math.h>
int main(){
    double a,b,c;
    double r1,r2;
    scanf("%lf%lf%lf",&a,&b,&c);
    r1 = (-1*b+sqrt(b*b-4*a*c))/(2*a);
    r2 = (-1*b-sqrt(b*b-4*a*c))/(2*a);
    printf("r1=%7.2lf\nr2=%7.2lf",r1,r2);
    return 0;
} 

 4.特殊符號輸出函數

想要輸出%或\,則須要在前面再加一個%或\學習

#include<stdio.h>
int main(){
    printf("%%\n");
    printf("\\");
    return 0;
} 

 5.getchar與putchar的使用

getchar用來接收輸入的單個字符,putchar用來輸出單個字符

#include<stdio.h>
int main(){
    char a,b,c;
    a = getchar();
    getchar();
    b = getchar();
    c = getchar();
    putchar(a);
    putchar(b);
    putchar(c);
    return 0;
} 
/*輸入數據:abcd
  輸出數據:abd
  緣由:字符b雖然被接收,可是沒有用變量進行保存,因此丟失
  ps:getchar能夠接收Enter鍵的內容,以\n的形式保存 
  */ 

 6.經常使用math函數(使用需加頭文件#include<math.h>)

1)fabs(double x)

該函數用於對double型變量取絕對值

#include<stdio.h>
#include<math.h> 
int main(){
    double db =-12.56;
    printf("%.2f\n",fabs(db));
    return 0;
} 
//輸出結果:12.56 

2)floor(double x)和ceil(double x)

這兩個函數分別用於double型變量的向下取整和向上取整,返回類型爲double型

#include<stdio.h>
#include<math.h> 
int main(){
    double db1 = -5.2, db2 = 5.2;
    printf("%.0f %.0f\n",floor(db1),ceil(db1));
    printf("%.0f %.0f\n",floor(db2),ceil(db2));    
    return 0;
} 
/*輸出結果:
-6 -5
5 6*/

3)pow(double r,double p)

該函數用於返回rp,要求r和p都是double型

#include<stdio.h>
#include<math.h> 
int main(){
    double db = pow(2.0,3.0);
    printf("%f\n",db);    
    return 0;
    /*int型也可使用 
    int a=2,b=3;
    int db2 = pow(a,b);
    print("%d\n",db2)
    */
} 
/*輸出結果:
8.000000
*/

4)sqrt(double x)

該函數用於返回double型變量的算術平方根

#include<stdio.h>
#include<math.h> 
int main(){
    double db = sqrt(2.0);
    printf("%f\n",db);
    return 0;
} 
/*輸出結果:
1.414214
*/

5)log(double x)

該函數用於返回double型變量的以天然對數爲底的對數

ps:C語言中沒有對任意底數求對數的函數,所以必須使用換底公式來將不是以天然對數爲底的對數轉換爲以e爲底的對數,即logab=loge/ logea

#include<stdio.h>
#include<math.h> 
int main(){
    double db = log(1.0);
    printf("%f\n",db);
    return 0;
} 
/*輸出結果:
0.000000
*/

 6)round(double x)

該函式用於將double型變量x四捨五入,返回類型也是double型,需進行取整

#include<stdio.h>
#include<math.h>
int main(){
    double db1 = round(3.40);
    double db2 = round(3.45);
    double db3 = round(3.50);
    double db4 = round(3.55);
    double db5 = round(3.60);
    printf("%d, %d, %d, %d, %d\n",(int)db1,(int)db2,(int)db3,(int)db4,(int)db5);
    return 0;
} 
//輸出結果:3,3,4,4,4 

7.switch語句的用法

格式:

switch(表達式){
    case 常量表達式1:
        ...
        break;
    case 常量表達式2:
        ...
        break;
        
    ...
    
    case 常量表達式n:
        ...
        break;
    default:
        ... 
}

實例:

#include<stdio.h>
int main(){
    
    int a = 1, b = 2; 
    switch(a + b){
        case 1:
            printf("%d\n",a);
            break;
        case 2:
            printf("%d\n",b);
            break;
        case 3:
            printf("%d\n",a + b);
            break;
        default:
            printf("None\n");
    }
    return 0;
} 
//輸出結果:3

 

8.求圓周率π的近似值

題目連接:圓周率近似值(點擊此處)

因爲題目沒有給出解法,也沒有相關提示,因此我就參考了一下別人的解法,這裏的核心就是求圓周率近似值的公式:

針對本題的代碼:

#include<stdio.h>
#include<math.h> 
int main(){//解法:用π/4 ≈ 1 - 1/3 + 1/5 - 1/7 +... 公式
     int n=1;
     double ans;//結果 
     double tmp = 1.0;//分子 
     while(n<=pow(10,6)){//題中要求爲某一項絕對值小於10的-6次方,即1/n裏的n要大於10的六6次方 
         ans += tmp/n*1.0;
         n = n + 2;
         tmp = tmp*-1.0;
     }
     ans = ans * 4;
     printf("PI=%10.8f\n",ans); 
} 

 

9.Fibonacci數列

題目連接:http://www.codeup.cn/problem.php?cid=100000568&pid=7

1)遞歸法求解

#include<stdio.h>
#include<math.h>
int Fib(int n){
    if(n==1||n==2){
        return 1;
    }else{
        return Fib(n-1)+Fib(n-2);
    }
} 
int main(){
     int n;
     scanf("%d",&n);
     printf("%d",Fib(n));
     return 0;
} 

2)概念法求解

#include<stdio.h>
#include<math.h>
int Fib(int n){
    int i;
    int f1 = 1;
    int f2 = 1;
    int f3 = 1;//避免判斷n是否大於2 
    for(i = 2;i<n;i++)
    {
        f3 = f1 + f2;
        f1 = f2;
        f2 = f3;
    }
    return f3;
} 
int main(){
     int n;
     scanf("%d",&n);
     printf("%d",Fib(n));
     return 0;
} 

【轉】參考博客地址:https://blog.csdn.net/weixin_40740059/article/details/80012909

 

10.分數序列求和

題目描述:有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13…求出這個數列的前 20 項之和。

#include<stdio.h>
int main(){
     double n1=2.0,m1=1.0;
     double n2=3.0,m2=2.0;
     double n3,m3;
     double ans=(n1/m1)+(n2/m2);
     for(int i=3;i<=20;i++){
         n3 = n1 + n2;
         m3 = m1 + m2;
         ans+=(n3/m3);
         n1 = n2;
         m1 = m2;
         n2 = n3;
         m2 = m3;
     }
     printf("%.6f\n",ans);
     return 0;
} 

 

 11.冒泡排序

冒泡排序是排序中最基本的一種方法,雖然在寫題時咱們通常不會去使用它,但我以爲了解冒泡排序算法的實現原理確實很是必要的。

冒泡排序的本質在於交換,即每次經過交換的方式把當前剩餘元素的最大值移動到一端,當剩餘元素爲0時,排序結束。

這裏附上一個輔助學習數據結構的網站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html(模擬常見數據結構的運行過程)

#include<stdio.h>
int main(){
    int a[10]={3,1,4,5,2};
    for(int i=1;i<=4;i++){//進行n-1趟比較 
        for(int j=0;j<5-i;j++){//將剩餘的數進行交換,選出最大的那一個 
            if(a[j]>a[j+1]){//交換 
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }
    for(int i=0;i<5;i++){
        printf("%d ",a[i]);
    }
    return 0;
} 
//輸出結果:1 2 3 4 5

 題目連接:http://www.codeup.cn/problem.php?cid=100000569&pid=7

 

12.二維數組的初始化

#include<stdio.h>
int main(){
    int a[5][6]={{3,1,2},{8,4},{},{1,2,3,4,5}};
    for(int i=0;i<5;i++){
        for(int j=0;j<6;j++){
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
    return 0;
} 
/*輸出結果:
3 1 2 0 0 0
8 4 0 0 0 0
0 0 0 0 0 0
1 2 3 4 5 0
0 0 0 0 0 0
*/ 

特別提醒:若是數組大小較大(大概是106),則須要將其定義在主函數外,不然會使程序異常退出,緣由是函數內部申請的局部變量來自系統棧,容許申請的空間較小;而函數外部申請的全局變量

來自靜態存儲區,容許申請的空間較大。

 

13.memset函數的使用

memset函數的功能是給數組中的每個元素都賦予相同的值

使用格式:memset(數組名,值,sizeof(數組名))

注意:使用需加頭文件 #include<string.h>,另外只建議使用memset賦0或-1

#include<stdio.h>
#include<string.h>
int main(){
    int a[5]={1,2,3,4,5};
    memset(a,0,sizeof(a));
    for(int i=0;i<5;i++){
        printf("%d ",a[i]);
    }
    printf("\n");
    memset(a,-1,sizeof(a));
    for(int i=0;i<5;i++){
        printf("%d ",a[i]);
    }
    printf("\n");
    return 0;
} 
/*輸出結果:
0 0 0 0 0 0
-1 -1 -1 -1 -1
*/ 

 

14.字符數組初始化

#include<stdio.h>
#include<string.h>
int main(){
    char str[15] = {'G','O','O','D',' ','B','O','Y','!'};
    for(int i=0;i<9;i++){
        printf("%c",str[i]);
    }
    printf("\n");
    return 0;
} 
/*輸出結果:
GOOD BOY!

*/ 

除此以外,字符數組也能夠經過賦值字符串來初始化(僅限於初始化,程序其它位置不容許這樣直接賦值整個字符串

#include<stdio.h>
#include<string.h>
int main(){
    char str[15] = "GOOD BOY!";
    for(int i=0;i<9;i++){
        printf("%c",str[i]);
    }
    printf("\n");
    return 0;
} 
/*輸出結果:
GOOD BOY!

*/ 

 

15.字符數組的輸入輸出

1)scanf輸入,printf輸出

scanf對字符類型有%c和%s兩種格式(printf同理),其中%c用來輸入輸出單個字符,%s用來輸入一個字符串並存在數組裏或輸出一個字符串。

%c能識別空格和換行,%s將空格和換行識別一個字符串的結束。

#include<stdio.h>
int main(){
    char str[10];
    scanf("%s",str);
    printf("%s\n",str);
    return 0;
} 

/*
輸入:
ATA QAQ 
輸出結果:
ATA 
*/ 

scanf輸入%s不須要加&。

2)getchar輸入,putchar輸出

getchar和putchar分別用來輸入輸出單個字符

#include<stdio.h>
int main(){
    char str[5][5];
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            str[i][j]=getchar();
        }
        getchar();//用來吸取每行結束輸入的換行符(enter鍵) 
    }
    for(int i = 0;i<3;i++){
        for(int j=0;j<3;j++){
            putchar(str[i][j]);
        }
        putchar('\n');
    } 
    return 0;
} 

/*
輸入:
ATA
QAQ
ATA
輸出結果:
ATA
QAQ
ATA

*/ 

3)gets輸入,puts輸出

gets用來輸入一行字符串(注意:gets識別換行符\n做爲輸入結束,所以scanf完一個整數後,若是使用gets,需先用getchar接收輸入整數後的換行符),並將其存放於一維數組中;

puts用來輸出一行字符串,並緊跟一個換行

#include<stdio.h>
int main(){
    char str1[20];
    char str2[5][10];
    gets(str1);
    for(int i=0;i<3;i++){
        gets(str2[i]);
    } 
    puts(str1);
    for(int i=0;i<3;i++){
        puts(str2[i]);
    }
    return 0;
} 

/*
輸入:
abcdefghi
QAQ
ATA
ATA
輸出結果:
abcdefghi
QAQ
ATA
ATA

*/ 

特別提醒:gets和scanf的輸入方式會默認在每一個字符串的後面添加一個空字符'\0',而後puts和printf就是經過識別'\0'做爲字符串的結尾輸出的。

因此若是不是使用scanf的%s格式或者gets函數輸入字符串,必定要在字符串的結尾加上'\0',不然使用printf和puts進行輸出時會出錯。

#include<stdio.h>
int main(){
    char str[20]={'a','b','\0','a','b','c'};
    printf("%s",str);
    return 0;
} 

/*
輸入:

輸出結果:
ab

*/ 

 

16.#include<string.h>頭文件

string頭文件包含了許多用於字符數組的函數。使用如下函數須要在程序開頭田間string.h頭文件

1)strlen()

strlen函數能夠獲得字符數組中第一個\0前的字符的個數

格式:strlen(字符數組)

#include<stdio.h>
#include<string.h>
int main(){
    char str1[20];
    char str2[20]={'a','b','c','\0','a','b','c'};
    gets(str1);
    int len = strlen(str1);
    printf("%d\n",len);
    printf("%d\n",strlen(str2));
    return 0;
} 

/*
輸入:
abcabc
輸出結果:
6
3
*/ 

2)strcmp()

strcmp函數返回兩個字符串大小的比較結果,比較原則是按字典序

格式:strcmp(字符數組1,字符數組2)

strcmp的返回結果:

①字符數組1<字符數組2,返回一個負整數

②字符數組1==字符數組2,返回0

③字符數組1>字符數組2,返回一個正整數

#include<stdio.h>
#include<string.h>
int main(){
    char str1[50],str2[50];
    gets(str1);
    gets(str2);
    int cmp = strcmp(str1,str2);
    if(cmp<0){
        printf("str1 < str2\n");
    }else if(cmp==0){
        printf("str1 = str2\n");
    }else{
        printf("str1 > str2\n");
    }
    return 0;
} 

/*
輸入:
abc
def
輸出結果:
str1 < str2
*/ 

3)strcpy()

strcpy函數能夠把一個字符串複製給另一個字符串

strcpy(字符數組1,字符數組2)

注意:是吧字符數組2複製給了字符數組1,這裏的「複製」包括告終束符\0

#include<stdio.h>
#include<string.h>
int main(){
    char str1[50],str2[50];
    gets(str1);
    gets(str2);
    strcpy(str1,str2);
    puts(str1);
    return 0;
} 

/*
輸入:
abc
def
輸出結果:
def
*/ 

4)strcat()

strcat()能夠把一個字符串拼接到另外一個字符串後面

格式:strcat(字符數組1,字符數組2)

注意:是把字符數組2的內容拼接到字符數組1的後面

#include<stdio.h>
#include<string.h>
int main(){
    char str1[50],str2[50];
    gets(str1);
    gets(str2);
    strcat(str1,str2);
    puts(str1);
    return 0;
} 

/*
輸入:
abc
def
輸出結果:
abcdef
*/ 

 

17.有序插入

#include<stdio.h>
int main(){
    int a[10];
    for(int i=0;i<9;i++){
        scanf("%d",&a[i]);
    }
    int n;
    scanf("%d",&n);
    int k;
    for(int i=0;i<9;i++){
        if(n<a[i]){
            k=i;
            for(int j=9;j>=i;j--){
                a[j]=a[j-1];
            }
            break;
        }
    }
    a[k]=n;
    for(int i=0;i<10;i++){
        printf("%d\n",a[i]);
    }
    return 0;
}

 

18.數組元素逆置

 

交換法

#include<stdio.h>
int main(){
    int a[10];
    for(int i=0;i<10;i++){
        scanf("%d",&a[i]);
    }
    for(int i=0;i<5;i++){
        int temp=a[9-i];
        a[9-i]=a[i];
        a[i]=temp;
    }
    for(int i = 0;i<10;i++){
        printf("%d\n",a[i]);
    }
    return 0;
}

 

19.解密(字符的規則變換)

思路:利用ascll碼錶

#include<stdio.h>
#include<string.h>
int main(){
    char a[100];
    scanf("%s",a);
    int len = strlen(a);
    for(int i=0;i<len;i++){
        if(a[i]>='A'&&a[i]<='Z'){
            a[i]='Z'-a[i]+'A';
        }else if(a[i]>='a'&&a[i]<='z'){
            a[i]='z'-a[i]+'a';
        }
    }
    printf("%s\n",a);
    return 0;
}

 

20.以數組做爲函數參數

數組做爲參數時,參數中數組的第一維不須要填寫長度(若是是二維數組,那麼第二維須要填寫長度),實際調用是也只須要填寫數組名。

特別提醒:數組做爲參數時,在函數中對數組元素的修改就等同因而對原數組元素的修改(這與普通的局部變量不一樣)

 

#include<stdio.h>
#include<string.h>
void change(int a[],int b[][5]){
    a[0] = 1;
    a[1] = 3;
    a[2] = 5;
    b[0][0] = 1;
}
int main(){
    int a[3] = {0};
    int b[5][5] = {0};
    change(a,b);
    for(int i=0;i<3;i++){
        printf("%d\n",a[i]);
    }
    printf("%d\n",b[0][0]);
    return 0;
} 
/*輸出結果
1
3
5
1

/* 

雖然數組能夠做爲參數,可是卻不容許做爲返回類型的出現。若是想返回數組,只能用上面的方法,將想要返回的數組做爲參數傳入。

 

21.字符串的逆序存放

利用以前的置換思想,將這些字母首尾對應交換位置便可實現字符串的逆序存放

#include<stdio.h>
#include<string.h>
void turnout(char a[]){
    int len=strlen(a);
    for(int i=0;i<len/2;i++){
        char temp = a[i];
        a[i] = a[len-1-i];
        a[len-1-i] = temp;
    } 
}
int main(){
    char a[20];
    gets(a);
    turnout(a);
    puts(a);
    return 0;
} 

 

22.提取字符串中的元音字母

本題牽扯到數組傳參,以及字符串判斷結束的條件

#include<stdio.h>
#include<string.h>
void extractV(char a[],char b[]){
    int len=strlen(a);
    int j=0;
    for(int i=0;i<len;i++){
        if(a[i]=='a'||a[i]=='A'||a[i]=='e'||a[i]=='E'||a[i]=='i'||a[i]=='I' \
        ||a[i]=='o'||a[i]=='O'||a[i]=='u'||a[i]=='U'){
            b[j] = a[i];
            j++;
        }
    }
    b[j]='\0';//這裏就要注意結尾的結束符 
}
int main(){
    char a[20];
    char b[20];
    gets(a);
    extractV(a,b);
    puts(b);
    return 0;
} 

 

23.指針變量

又到了這個使人頭疼的問題,我大一C語言學習之路就終結在指針部分,以後真的就再也看不下去了,這也直接影響了我對鏈表的學習,噩夢開始的地方,藉此機會,必定攻克這個難關。

 

指針變量用來存放指針,指針變量的定義與普通變量有所區別,它在某種數據類型後加星號*來表示這是一個指針變量。

int* p;
double* p;
char* p; 

注意:*放在數據類型以後或者變量名以前都是能夠的。

其中C程序員習慣於把*放在變量名以前,即「int *p」;C++程序員更習慣於把*放在數據類型以後。

 

若是一次須要同時定義幾個類型相同的指針變量,則須要在每一個變量名以前都加上*。

int *p1,*p2,*p3;

 

指針變量存放的是地址,而&則是取地址運算符,所以給指針變量賦值的方式通常是把變量的地址取出來,而後賦給對應類型的指針變量

int a;
int* p = &a;

這裏須要注意的是,int*是指針變量的類型,然後面的p纔是變量名,用來存儲地址,所以&a是賦給p的而不是賦給*p的

 

對於一個指針變量存放的地址,咱們能夠經過*(能夠看做開啓地址的鑰匙)來獲取這個地址所指的元素。

#include<stdio.h>
int main(){
    int a;
    int* p = &a;
    a = 3;
    printf("%d\n",p);//p裏面存放a的地址
    printf("%d\n",*p);//使用*(至關於鑰匙),打開p地址裏面存放的數據。
    printf("%d\n",*(&a));//這裏就至關於&a是一個地址,而後*是一把打開地址的鑰匙,
                      //因此*(&a)就應該是&a裏面存儲的數據。 
    return 0;
}
/*輸出結果:
6487620
3
3 
*/ 

 

另外,指針變量能夠進行加減法,其中減法的結果就是兩個地址偏移的距離。對於一個int*型的指針變量p來講,p+1是指p所指的int型變量的下一個int型變量地址

 

24.指針與數組

數組在地址上都是連續的,這樣能夠在元素前面加上取址運算符&來獲取它的地址,例如a[0]的地址爲&a[0],即數組a的首地址爲&a[0]。在c語言中,數組名稱能夠看成數組的首地址使用,即a == &a[0]

#include<stdio.h>
int main(){
    int a[10]={1,2,3};
    int* p = a;
    printf("%d\n",*p;
    printf("%d\n",*p+1);//指針加法的使用 
    printf("%d\n",*p+2);
    return 0;
}
/*輸出結果:
1
2
3 
*/ 

ps:在數組中 a+i == &a[i]

 

25.使用指針變量做爲函數參數

指針類型也能夠做爲函數參數的類型,這時視爲把變量的地址傳入參數。若是在函數中對這個地址中的元素進行改變,原先的數據就會確實地被改變

#include<stdio.h>
void change(int* p){
    *p = 233;
} 
int main(){
    int a = 1;
    int* p = &a;
    change(p);
    
    printf("%d\n",a);
    return 0;
}
/*輸出結果:
233
*/ 

 

26.引用傳遞

引用是c++中的語法,能夠不經過指針就能修改傳入的參數,對引用變量的操做就是對原變量的操做。使用方法:只須要在函數的參數類型後面加個&就能夠了。

#include<stdio.h>
void change(int &a){
    a = 123;
} 
int main(){
    int a = 10;
    change(a);
    printf("%d\n",a);
}
/*輸出結果:
123
*/ 

 

27,將指針類型參數傳遞與數組相結合的題目

#include<stdio.h>
#include<string.h>
void input(int* p){
    for(int i = 0;i<10;i++){
        scanf("%d",p+i);
    }
    
}
void process(int* p){
    int min=9999;
    int max=-1;
    int maxi,mini;
    for(int i = 0;i<10;i++){
        if(*(p+i)>max){
            max = *(p+i);
            maxi = i;
        }
        if(*(p+i)<min){
            min = *(p+i);
            mini = i;
        }
    }
    int temp1 = *p;
    *p = *(p+mini);
    *(p+mini) = temp1;
    int temp2 = *(p+9);
    *(p+9) = *(p+maxi);
    *(p+maxi) = temp2;
}
void print(int* p){
    for(int i = 0;i<10;i++){
        printf("%d ",*(p+i));
    }
}
int main(){
    int a[10];
    int* p = a;
    input(p);
    process(p);
    print(p);
    return 0;
}

 

28.訪問結構體內的元素

#include<stdio.h>
struct student{//結構體的定義 
    int id;
    char name[20];
    student* next;
}stu,*p;//變量的聲明 
int main(){
    p = &stu;
    stu.id = 5; 
    printf("%d\n",stu.id);//普通變量經過.訪問 
    printf("%d\n",(*p).id);//指針變量能夠經過.訪問 
    printf("%d\n",p->id);//也能夠經過->訪問 
    return 0;    
} 
/*
輸出結果:
5
5
5
*/

 

29.cout控制double型精度輸出

須要使用頭文件#include<iopmanip>

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
    cout<<setiosflags(ios::fixed)<<setprecision(2)<<123.4567<<endl;
    return 0;
}
//輸出結果:123.46 

 

30.浮點數的比較

浮點數在計算機裏的存儲並不老是精確的,這種狀況會給比較帶來麻煩,由於在C/C++中「==」要徹底相同結果纔會斷定爲true,因而須要引用一個極小數eps來對這種偏差進行修正。

經驗代表,eps取10-8是一個合適的數字——對於大多數的狀況既不會漏判也不會誤判,因此能夠將eps定義爲常量1e-8:

const double eps = 1e-8; 

爲了使比較更加方便,能夠把比較操做寫成宏定義的形式:

#define Equ(a,b) ((fabs((a)-(b)))<eps) //判斷相等

若是想使用不等於,只須要在Equ前面加上一個非運算符「!」便可(!Equ(a,b))。因而就能夠在程序中使用Equ函數來對浮點數進行比較了:

#include<stdio.h>
#include<math.h>
const double eps = 1e-8;
#define Equ(a,b) ((fabs((a)-(b)))<(eps))
int main(){
    double db = 1.23;
    if(Equ(db,1.23)){
        printf("True\n");
    }else{
        printf("False\n");
    }
    return 0;
}
//輸出結果:True 

經常使用的浮點數比較宏定義:

#define Equ(a,b) ((fabs((a)-(b)))<(eps)) //等於
#define More(a,b) (((a)-(b))>(esp)) //大於
#define Less(a,b) (((a)-(b))<(-esp))//小於
#define MoreEqu(a,b) (((a)-(b))>(-esp))//大於等於
#define LessEqu(a,b) (((a)-(b))<(esp))//小於等於

 

31.圓周率

圓周率Π不須要死記,由於由cos(Π)=-1可知Π=arccos(-1)。所以把Π寫成常量acos(-1.0)便可。

#include<stdio.h>
#include<math.h>
const double Pi = acos(-1.0);
 
int main(){
    printf("%f\n",Pi);
    return 0;
}
//輸出結果:3.141593

 

32.多點測試輸入方式

1)While...EOF型

while(scanf("%d",&n)!=EOF){
    ...
}
//字符串
while(scanf("%s",str)!=EOF){
  ...
}
while(gets(str)!=NULL){
  ...
}

2)While...break型

在while...EOF的內部判斷,知足條件,break跳出

3)while(T--)型

 

33.結構體指針實例

#include<stdio.h>
#include<iostream>
using namespace std;
struct student{
    int num;
    char name[20];
    char sex;
    int age;
};
int main(){
    int n;
    scanf("%d",&n);
    student s[20];
    student *stu = s;
    for(int i = 0;i < n;i++){
        //scanf("%d%s%c%d",(stu+i)->num,(stu+i)->name,(stu+i)->sex,(stu+i)->age);
        cin>>(stu+i)->num>>(stu+i)->name>>(stu+i)->sex>>(stu+i)->age;
    }
    for(int i=0;i<n;i++){
        //printf("%d %s %c %d\n",(stu+i)->num,(stu+i)->name,(stu+i)->sex,(stu+i)->age);
        cout<<(stu+i)->num<<' '<<(stu+i)->name<<' '<<(stu+i)->sex<<' '<<(stu+i)->age<<endl;
    }
    return 0;
}

仍有一個問題困惑着我,爲何使用scanf和printf輸入輸出會出錯(註釋掉的部分)。

 

34.%s後輸入%c,%c會接收%s後的空格,從而使數據不能正常接收。

#include<stdio.h>
int main(){
    int a;
    char b[20];
    char c;
    char d;
    scanf("%d%s%c%c",&a,b,&c,&d);
    printf("%d %s %c %c\n",a,b,c,d);
    return 0;
}
/*
輸入:1 Li c
輸出:1 Li   c   (第三個參數爲空格) 
*/ 

此問題目前可用cin,cout輸入輸出解決。

 問題緣由以及解決方法:https://blog.csdn.net/qq_40977765/article/details/79911312

 

35.競賽及機試中會用到的輸入格式練習:http://www.codeup.cn/contest.php?cid=100000574

相關文章
相關標籤/搜索