1. 程式人生 > >c語言自定義函式,10月28日總結

c語言自定義函式,10月28日總結

現在時間23點34分,我想看看我幾點能完成

 

今天總結自定義函式的使用,先從最基礎的地方開始

1.形參實參

在定義函式的時候,函式大多數都有引數,在被主調函式需要傳遞資料給函式的引數

函式定義時用的變數叫形參

傳遞給函式的中形參值或變數叫實參

int main()
{
    double a = 12.2;
    double C = circle(2.1111); //a 是實參,實參可以是你變數,也可以是常量
    printf("圖的周長為:%F\n", C);
}
double circle( double r)      // 這裡r 是形參 形參一定是一個變數
{
    return 3.1415926 * 2 * r; //返回值的型別一定是定義的函式型別,這裡是double
}

注意:
1形參在未出現函式呼叫時,他們並不佔用記憶體單元,只有在發生函式呼叫的時候形參才被分配記憶體,函式呼叫完成後,形參所佔的記憶體被釋放
2實參可以是變數,常量或者表示式
3在定義函式時,一定要指定形參的資料型別
4形參與實參的資料型別一定要可相容
5在C語言中,實參與形參的資料傳遞是“值傳遞”,即單向傳遞,只由實參傳遞給形參,而不能由形參傳遞給實參。

2.函式的宣告,所有自定義函式呼叫之前要做宣告

#include<stdio.h>
 
//使用函式前,需要在main函式前對使用的函式進行宣告
int getMax(int, int);

3.函式的返回值

1、什麼是返回值

    返回值是一個函式的處理結果,
2、為什麼要有返回值
    如果我們需要在程式中拿到函式的處理結果做進一步的處理,則需要函式必須有返回值
3、函式的返回值的應用
    直接用.....
    格式為:

        return 值

注意:
        1、return是一個函式結束的標誌,函式內可以有多個return,
            但只要執行一次,整個函式就會結束執行
        2、return 的返回值無型別限制,即可以是任意資料型別
        3、return 的返回值無個數限制,即可以用逗號分隔開多個任意型別的值
                          0個:返回None,ps:不寫return預設會在函式的最後一行新增return None
                         1個:返回的值就是該值本身

                         多個:返回值是元組

需要強調的是,一個函式中可以有多個 return 語句,但並不是所有的 return 語句都起作用。執行到哪個 return 語句,就是哪個 return 語句起作用,該 return 語句後的其他語句就都不會執行了。

func test(x, int, y int) int {
    return x + y
}
2、沒有返回型別
func test(x int ,y int){
   fmt.Println(x+y)
}
3、多個返回值

 
func test(x int, y int) (int, int, int) {
    return x + y, x, y
}

4.形參的改變不能改變實參的值

比如swap函式,如果不引用指標的話在形參裡修改的數值不會傳到主函式裡面

(1)形參出現在函式定義中,在整個函式體內都可以使用, 離開該函式則不能使用。
(2)實參出現在主調函式中,進入被調函式後,實參變數也不能使用。 
(3)形參和實參的功能是作資料傳送。

(4)發生函式呼叫時, 主調函式把實參的值傳送給被調函式的形參從而實現主調函式向被調函式的資料傳送。

5.swap函式實現方法,指標

#include <stdio.h>
void _swap(int *px, int * py) //因為標準庫已經有swap,為了區分,你應該定義成_swap,當然也可以是別的函式名
{
int temp = *px;
*px = *py;
*py = temp;
}
int power(int x)
{
return x * x;
}
int main() // main函式本身用來測試和呼叫,構成一個完整的程式
{
int x, y;
printf("請輸入x,y\n");
scanf("%d, %d", &x, &y);
_swap(&x, &y);
printf("交換後 x=%d, y=%d\n", x, y);
printf("power(x)=%d\n", power(y)); //此時的x是y
}

如上文所提到的,如果直接用自定義函式裡面的數值做交換並不會吧值傳給主函式,除了return,所以我們要用的指標,如果函式的引數是指標型別變數,在呼叫該函式的過程中,傳給函式的是實參的地址,在函式體內部使用的也是實參的地址,即使用的就是實參本身。所以在函式體內部可以改變實參的值。

這裡有個具體實現swap函式的地址:https://blog.csdn.net/apollon_krj/article/details/51445885

6.函式的遞迴

①遞迴的定義:一個函式在它的函式體內呼叫它自身,這種呼叫過程稱為遞迴,這種函式稱為遞迴函式。
②在遞迴呼叫中,主調函式又同時是被調函式。執行遞迴函式將反覆呼叫其自身,每呼叫一次就進入新的一層。
③執行遞迴函式將無休止地呼叫其自身,這當然是不正確的,為了防止遞迴呼叫無終止的進行,就必須在函式內有終止遞迴的條件判斷語句,滿足某種條件後就不再作遞迴呼叫,然後逐層返回!!!這也是使用遞迴的難點。

遞迴:執行一個過程中需要再次呼叫該過程。 
它的特點是,一個過程運算中再次用到該過程。* 
他的思路是,從後往前推理。

(1)接受一個整形值(無符號),把它轉換為字元並列印它

void fun(int x)
{
    if (x > 9)
    {
        fun(x/10);
    }

    printf("%d\n", x%10);

}
int main()
{
    int a = 1234;
    fun(a);
    system("pause");
    return 0;
}

(2)求n的階乘

int factorial(int x)
{
    if (x <= 1)
        return 1;
    else
        return x* factorial(x - 1);
}
int main()
{
    int x = 5;
    factorial(x);
    system("pause");
    return 0;
}

(3)斐波那契數列

int fib(int x)
{
    if (x <= 2)
        return 1;
    else
        return fib(x - 1) + fib(x - 2);
}
int main()
{
    int x = 4;
    printf("%d",fib(x));
    system("pause");
    return 0;
}

(4)gcd函式

int Gcd(int a,int b)
{
    if(b == 0) return a;
    return Gcd(b,a%b);
} 

6.函式的迭代

通過迴圈不斷重複一個過程,這個過程是一個或若干個舊值通過該過程獲得一個或若干個新值的過程,而得到的新值又充當下一個相同過程的舊值,直到迴圈得到自己期望的結果。迴圈執行一次過程就是一次迭代。**迭代不是迴圈,迭代需要用到迴圈。 
它的特點是,一個過程結束後再次進行該過程。 
它的思路是,從前往後推理。
 

(1)gcd函式

int Gcd(int a,int b)
{
    while(b != 0)
    {
        int r = b;
        b = a%b;
        a = r;
    }
    return a;
} 

(2)斐波那契數列

#include<stdio.h>
    double  Fibonacci(unsigned int n)
    {
    if(n==1||n==2)
    return 1;
    double value;
    double a=1,b=1;
    for(unsigned int i=3;i<=n;i++)
    {
    value=a+b;
    a=b;
    b=value;
    }
    return value;
    }
int main()
    {
    int c;
    printf("請輸入一個數:");
    scanf("%d",&c);
    printf("%.0lf\n",Fibonacci(c));
    return 0;
}

 

7.自定義函式的應用

#include<stdio.h>
int main()
{
    int n = 0;
    int j = 0;
    int k = 0;
    printf("輸入你想要的乘法表數:");
    scanf("%d", &n);
    for (k = 1; k <= n; k++)
    {
        for (j = 1; j <= k; j++)
        {
            printf("%2d x %2d = %2d ", j, k, j*k);
        }
        printf("\n");
    }
    return 0;
}

列印一個9*9乘法表

#include<stdio.h>
int judge_leap_year(int year)
{
    if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400)
        return 1;
    else
        return 0;
}
int main()
{
    int year = 0;
    printf("輸入年份:");
    scanf("%d", &year);
    if (judge_leap_year(year))
        printf("%d是閏年。\n", year);
    else
        printf("%d不是閏年。\n",year);
    return 0;
}

判斷是不是閏年

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
    int number = 57;
    int num = 0;
start:  scanf("%d", &num);
    if (num == number)
    {
        printf("猜對了!\n");
    }
    else if (num > number)
    {
        printf("大了,重新猜一下吧。\n");
        goto start;
    }
    else
    {
        printf("小了,重新猜一下吧。\n");
        goto start;
    }
    return 0;
}

猜數字

#include<stdio.h>
#include<math.h>
//返回-1,輸入有誤
//返回1,是素數
//返回因子,不是素數
int IsPrimeNumber(int number)
{
    if (number <= 1)//質數是大於1的自然數
        return -1;
    int rooting = (int)sqrt(number);
    for (int i = 2; i <= rooting; ++i)
    {
        if (number%i == 0)
            return i;
    }
    return 1;
}

int main()
{
    int number = 0;
    int result = 0;
    while (1)
    {
        printf("Please input a number : ");
        scanf("%d", &number);
        result = IsPrimeNumber(number);
        if (result == -1)
            printf("Input invalid.\n");
        else if (result == 1)
            printf("%d is primer.\n", number);
        else
            printf("%d isn't primer,factor is %d.\n", number,result);
    }
    return 0;
}

判斷一個數是不是素數

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

文獻引用:

https://blog.csdn.net/qq_43001579/article/details/81940038

https://blog.csdn.net/a1376871144/article/details/83479184

https://blog.csdn.net/pangqiandou/article/details/52772599

https://blog.csdn.net/weixin_42153410/article/details/80296299

https://blog.csdn.net/csdn_kou/article/details/80239069

https://blog.csdn.net/loterior/article/details/78322461

https://blog.csdn.net/walle2018/article/details/79341869

https://blog.csdn.net/HaloTrriger/article/details/78271539