重點內容:
函數:
定義:
????????返回值類型 函數名(參數列表) { //函數體 }
????????函數的參數列表中可以有多個數據
????????返回值:如果函數沒有返回值可以寫成void 返回值的作用,函數的結果用來返回給主調函數的,如果主調函數處不需要函數的結果,函數可以沒有返回值
????????參數:如果函數實現功能時,需要外部傳遞數據過來,那么函數就需要參數
????????寫在函數定義位置的參數叫做形式參數,沒有實際的意義,只起到占位作用????????
????????函數的定義不能嵌套????????
函數的分類:
????????是否需要自己定義:庫函數、自定義函數
????????是否被調用的角度:主調函數、被調函數
????????是否有返回值和參數的角度:
? ? ? ? ? ? ? ? 1.有參有返回值
? ? ? ? ? ? ? ? 2.有參無返回值
? ? ? ? ? ? ? ? 3.無參無返回值
? ? ? ? ? ? ? ? 4.無參有返回值
函數的調用:
????????函數名(實際參數);
????????實際參數的個數需要和形式參數的個數保持一致
????????函數調用的過程就是實參初始化形參的過程
????????函數定義的代碼不會執行,只有函數被調用時才會執行函數體
????????不同函數中的同名變量,互不相關
函數的返回值:
????????函數的返回值可以理解為函數調用的結果
函數聲明:
????????函數定義在函數調用下方時,需要函數聲明
????????格式: 返回值類型 函數名(參數類型);
????????作用: 告訴編譯器,函數的參數類型和返回值類型,讓編譯器可以找到該函數
數組作為函數參數傳遞:
????????所有出現在函數形參位置長得像數組定義的代碼,實際上都是指針????????
? ? ? ? void fun(int *p,int len) //一維整形數組:形參需要使用同類型的指針變量接收一維整形數組的地址,還需要傳一維整型數組的長度(因為在功能函數中不能求出數組的長度)
? ? ? ? void fun(char *p)//一維字符數組:只需要接收一維字符數組的首地址即可,不需要接收長度
? ? ? ? void?fun(int (*p)[3],int r,int c)//二維數組作為函數參數傳遞時,形參需要使用數組指針接收
指針函數:
全局變量和局部變量:
????????全局變量:不定義在任何括號中的變量,生命周期和作用域是程序的開始到結束
????????局部變量:定義在括號中的變量,生命周期和作用域是括號的開始到結束
如何區分生命周期和作用域:
????????生命周期:內存存在的時候
????????作用域:可以訪問的位置
static的使用:
????????static用于局部變量:延長局部變量的生命周期,編程程序的開始到結束
????????static修飾全局變量:不能在其他文件中訪問該全局變量
????????static修飾函數:不能在其他文件中調用函數
指針函數:
????????本質是一個函數,返回值是指針(一定是一個有返回值的函數)
????????返回值是函數返回到主調函數處的結果
????????總結:指針函數可以返回生命周期更長的變量的地址
動態內存分配:
????????申請堆區內存????????
malloc:
????????void *malloc(size_t size);
????????功能:從堆區申請指定字節數的空間
????????返回值:申請的堆區空間的首地址
????????參數:申請多少個Byte
free:
????????void free(void *ptr);
????????功能:釋放堆區內存
????????返回值:無
????????參數:萬能指針,接收任意類型的地址(要釋放空間的首地址)
內存泄漏:
????????堆區有空間沒有在使用,但是空間所有權沒有還給內存,導致無法從堆區申請空間,這種情況叫內存泄漏
????????如何避免內存泄漏,申請空間之后記得釋放
函數指針:
????????本質是一個指針,指向一個函數
????????int add(int a,int b) { return a+b; } -->int (*p)(int,int) = add;//返回值類型 (*函數指針名)(形參類型);?讓指針指向指定返回值類型和參數類型的函數
回調函數:
????????函數的其中一個參數是函數指針,由函數指針指向的函數來完成實際的功能
遞歸函數:
遞歸的三要素:
????????遞歸出口(沒有就是死遞歸)
????????遞歸邏輯
????????遞歸返回值
作業:
1.趕鴨子問題:一個人趕著鴨子去村莊賣,每經過一個村子賣出一半又一只,經過七個村莊后還剩下兩只鴨子,問出發時共趕了多少只鴨子
程序源碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int duck(int day)
{
if(day==7)return 2;
return(duck(day+1)+1)*2;
}
int main(int argc, const char *argv[])
{
printf("%d\n",duck(0));
return 0;
}
2.用遞歸輸出數的二進制
程序源碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int transform(int num)
{
if(num>1)
{
transform(num/2);
}
printf("%d",num%2);
}
int main(int argc, const char *argv[])
{
int num;
printf("請輸入需要轉換的數:");
scanf("%d",&num);
printf("after transform:");
transform(num);
putchar(10);
return 0;
}
3.遞歸輸出斐波那契數列
程序源碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int Fibonacci(int num)
{
if(num==1||num==2)
{
return 1;
}
return Fibonacci(num-1)+Fibonacci(num-2);
}
int main(int argc, const char *argv[])
{
int num;
printf("請輸入打印包含幾個元素的斐波那契數列:");
scanf("%d",&num);
printf("Fibonacci=");
for(int i=1;i<=num;i++)
{
printf("%d\t",Fibonacci(i));
}
putchar(10);
return 0;
}
4.整理思維導圖