最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言函數(shù)超詳細講解上篇

 更新時間:2022年04月18日 09:01:42   作者:初學C語言者  
函數(shù)是一組一起執(zhí)行一個任務的語句。每個?C?程序都至少有一個函數(shù),即主函數(shù)?main()?,所有簡單的程序都可以定義其他額外的函數(shù),函數(shù)我們分兩篇來講解,接下來開始第一篇

前言

本文主要學習函數(shù)的相關內容。

1、函數(shù)是什么?

維基百科中對函數(shù)的定義:子程序

  • 在計算機科學中,子程序(英語:Subroutine, procedure, function, routine, method,subprogram, callable unit),是一個大型程序中的某部分代碼, 由一個或多個語句塊組成。它負責完成某項特定任務,而且相較于其他代 碼,具備相對的獨立性。
  • 一般會有輸入參數(shù)并有返回值,提供對過程的封裝和細節(jié)的隱藏。這些代碼通常被集成為軟件庫。

2、C語言中函數(shù)的分類

  • 庫函數(shù)
  • 自定義函數(shù)

2.1 庫函數(shù)

  • 在學習C語言編程時,總是在一個代碼編寫完成之后,想把這個結果打印到屏幕上看看。這時使用一個功能:將信息按照一定的格式打印到屏幕上(printf)。
  • 在編程的過程中我們會頻繁的做一些字符串的拷貝工作(strcpy)
  • 在編程是我們也計算,總是會計算n的k次方這樣的運算(pow)

上面的函數(shù)不用自己編寫,直接可以調用。為了支持可移植性和提高程序的效率,所以C語言的基礎庫中提供了一系列類似的庫函數(shù),方便程序員進行軟件開發(fā)。

C語言常用的庫函數(shù)都有:

  • IO函數(shù)
  • 字符串操作函數(shù)
  • 字符操作函數(shù)
  • 內存操作函數(shù)
  • 時間/日期函數(shù)
  • 數(shù)學函數(shù)
  • 其他庫函數(shù)

使用庫函數(shù),必須包含 #include 對應的頭文件。

2.1.1 如何學會使用庫函數(shù)

推薦查詢工具官網:

MSDN(Microsoft Developer Network)

www.cplusplus.com

http://en.cppreference.com(英文版)

http://zh.cppreference.com(中文版)

2.1.2 自定義函數(shù)

自定義函數(shù)和庫函數(shù)一樣,有函數(shù)名,返回值類型和函數(shù)參數(shù)。這些都是我們自己來設計,函數(shù)的組成:

ret_type fun_name(para1, * )
{
	statement;//語句項
}
//ret_type 返回類型
//fun_name 函數(shù)名
//para1 函數(shù)參數(shù)
//舉例:寫一個函數(shù)可以找出兩個整數(shù)中的最大值
//get_max函數(shù)的設計
int get_max(int x, int y)
{
	return (x>y)?(x):(y);
}
int main()
{
	int num1 = 10;
	int num2 = 20;
	int max = get_max(num1, num2);
	printf("max = %d\n", max);
	return 0;
}

3、函數(shù)的參數(shù)

3.1 實際參數(shù)(實參)

  • 真實傳給函數(shù)的參數(shù),叫實參
  • 實參可以是:常量、變量、表達式、函數(shù)等
  • 無論實參是何種類型的量,在進行函數(shù)調用時,它們都必須有確定的值,以便把這些值傳送給形參

3.2 形式參數(shù)(形參)

  • 形式參數(shù)是指函數(shù)名后括號中的變量,因為形式參數(shù)只有在函數(shù)被調用的過程中才實例化(分配內存單元),所以叫形式參數(shù)
  • 形式參數(shù)當函數(shù)調用完成之后就自動銷毀了。因此形式參數(shù)只在函數(shù)中有效
//舉例2:寫一個函數(shù)可以交換兩個整形變量的內容
//實現(xiàn)成函數(shù),但是不能完成任務
int exchange1(int x, int y)
{//當實參傳給形參時候,形參是實參的一份臨時拷貝,
	//對形參的修改不會影響實參
	int temp = x;
	x = y;
	y = temp;
}
//正確的版本
int exchange2(int* pa, int* pb)//定義指針,接收地址
{
	int temp = *pa;
	*pa = *pb;
	*pb = temp;
}
int main()
{
	int a = 3;
	int b = 5;
	exchange1(a, b);//傳參是值
	printf("exchange1::a = %d b = %d\n", a, b);//交換前

	exchange2(&a, &b);//傳參是地址
	printf("exchange2::a = %d b = %d\n", a, b);//交換后的
	//傳入地址,自定義的形參和實參聯(lián)系更加緊密,能改變地址存儲的數(shù)值
	//此時,形參的地址與實參的地址是一樣的
	return 0;
}

上面代碼中, exchange1和 exchange2函數(shù)中的參數(shù) x,y,pa,pb 都是形式參數(shù)。在main函數(shù)中傳給 exchange1的 a ,b 和傳給 exchange2函數(shù)的 &a ,&b是實際參數(shù)。

運行結果如下所示,exchange1并沒有起到預想的交換數(shù)值的作用,exchange2可以。

在這里插入圖片描述

在這里插入圖片描述

通過監(jiān)視變量發(fā)現(xiàn):

名稱意義
a5數(shù)值為5
&a0x113f8e4數(shù)值a的地址
x5形參x數(shù)值為5
&x0x113f800形參x的地址
pa0x113f8e4形參pa數(shù)值為a的地址
  • 變量a在內存中開辟了空間,地址是0x113f8e4
  • 函數(shù)exchange1將實參a傳遞給形參x,x的數(shù)值也是5,但此時形參x另外重新再內存中開辟了空間,地址 0x113f800,形參和實參的地址是不一樣的
  • 函數(shù)exchange2將實參a傳遞給形參pa,pa的值是變量a的地址0x113f8e4,這個地址里面存放變量a的數(shù)值5。

在這里插入圖片描述

這里可以看到 exchange1函數(shù)在調用的時候, x , y 擁有自己的空間,同時擁有了和實參一模一樣的內容。所以我們可以簡單的認為:

形參實例化之后其實相當于實參的一份臨時拷貝。形參x、y的值發(fā)生交換,但是不影響實參a、b的值。一般性的只是使用數(shù)值大小,利用形參傳值就可以了,傳值表明,形參和實參的關系膚淺,僅限于表面數(shù)值的拷貝。

如果需要對主函數(shù)的實參值進行操作,比如交換,此時形參需傳地址,功能更為強大。傳地址表明,形參和實參的關系更深一步,直接可以通過地址修改實參的數(shù)值。

4、函數(shù)的調用

4.1 傳值調用

函數(shù)的形參和實參分別占有不同內存塊,對形參的修改不會影響實參。

4.2 傳址調用

  • 傳址調用是把函數(shù)外部創(chuàng)建變量的內存地址傳遞給函數(shù)參數(shù)的一種調用函數(shù)的方式
  • 這種傳參方式可以讓函數(shù)和函數(shù)外邊的變量建立起真正的聯(lián)系,也就是函數(shù)內部可以直接操作函數(shù)外部的變量

4.3 練習

4.3.1 判斷一個數(shù)是不是素數(shù)

寫一個函數(shù)可以判斷一個數(shù)是不是素數(shù)

//返回1 表示是素數(shù)
//返回-1 表示不是素數(shù)

//寫法1  2-n-1 試除法
int  is_sushu(int a)
{//素數(shù)就是除1和自身外,不能被其他數(shù)整除
	for (int i = 2; i < a-1; i++)
	{//用2-n-1的數(shù)一一試除
		if (a%i==0)
		{//若有能除的,直接返回-1,跳出后面的循環(huán)了
			return -1;//表明不是素數(shù),
		}
	}//break退出循環(huán)會調到這里
	//return返回時直接退出這個函數(shù)了,返回到主函數(shù)了,級別更高
	return 1;
}

int main()
{
	int a = 0;
	scanf("%d", &a);
	int num = is_sushu(a);
	if (num==1)
	{
		printf("%d: 是素數(shù)", a);
	}
	else
	{
		printf("%d:不是素數(shù)", a);
	}
	return 0;
}

//寫法2  2-sqrt(n) 試除法,速度更快
#include<math.h>
int  is_sushu(int num)
{
	for (int i = 2; i <=sqrt(num); i++)
	{
		if (num%i == 0)
		{
			return -1;
		}
	}
	return 1;
}

int main()
{
	int num = 0;
	for (int num = 100; num < 201; num++)
	{
		if ((is_sushu(num)) == 1)
		{
			printf("%d ", num);
		}
	}
	return 0;
}

4.3.2 判斷一年是不是閏年

寫一個函數(shù)判斷一年是不是閏年

//閏年時是4的倍數(shù)且不是100的倍數(shù),或者是400的倍數(shù)
int  is_run_nian(int y)
{
		if (((num%4 == 0)&& (num%100 != 0))|| (num % 400 == 0))
		{
			return 1;
		}
	//return ((num%4 == 0)&& (num%100 != 0))|| (num % 400 == 0);//簡寫
		
}
int main()
{
	int num = 0;
	for (int num = 1000; num <= 2000; num++)
	{
		if ((is_run_nian(num)) == 1)
		{
			printf("%d ", num);
		}
	}
	return 0;
}

4.3.3 二分查找

寫一個函數(shù),實現(xiàn)一個整形有序數(shù)組的二分查找

//找到了就返回下標
//找不到返回-1
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 0;
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;//左下標
	int right = sz - 1;//右下標

	scanf("%d", &k);
	while (left<=right)
	{//每次left right mid都要更新
		int mid = left + (right - left) / 2;		   
		if (arr[mid] > k)
		{//尋找的數(shù)值在左半邊,所以左不動,右邊動
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{//尋找的數(shù)值在右半邊,所以左邊動,右不動
			left = mid + 1;
		}
		else 
		{
			printf("找到了:%d ", mid);
			break;
		}
	}
	if (left>right)//循環(huán)結束了
	{
		printf("找不到");
	}
	return 0;
}

可以將二分法進行改進,寫成獨立的函數(shù),讓函數(shù)功能單一化:

int is_erfen(int arr[],int k, int sz)
{//數(shù)組傳遞參數(shù)進來就是數(shù)組首元素的地址,并不是整個數(shù)組
	//地址的大小是4或8個字節(jié),前面有講到過的
//x86平臺中,地址占4個字節(jié),sizeof(arr)是4, 而不是40了
	//int sz = sizeof(arr) / sizeof(arr[0]);//sz要在主函數(shù)計算,
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{//每次left right mid都要更新
		int mid = left + (right - left) / 2;
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 0;
	int i = 0;
	scanf("%d", &k);
	//主函數(shù)中  按數(shù)組名找到整個數(shù)組,求出占用字節(jié)是40
	int sz = sizeof(arr) / sizeof(arr[0]);
	int num = is_erfen(arr, k, sz);

	if (num ==-1)
	{
		printf("找不到"); 
	}
	else
	{
		printf("找到了:%d ", num);
	}
	return 0;
}

在這里插入圖片描述

在上面的函數(shù)中需要注意,數(shù)組的大小必須在主函數(shù)中計算,下面代碼可說明在主函數(shù)中和其他函數(shù)中求數(shù)組長度的區(qū)別:

int erfen(int arr[])
{//數(shù)組傳遞進來,只能是首地址,這個arr數(shù)組里只有{1},長度為4
	int sz1 = sizeof(arr) / sizeof(arr[0]);,//4/4 = 1求出只有1個元素
	printf("erfen求數(shù)組大小,sz1:%d\n ", sz1);
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };	
	//數(shù)組長度為40
	int sz = sizeof(arr) / sizeof(arr[0]);//40/4 = 10 求出數(shù)組10個元素
	printf("main中求數(shù)組大小,sz:%d\n ", sz);
	erfen(arr);	
	return 0;
}

在這里插入圖片描述

按F10進入調試界面,按F11,可觀察到:

  • 主函數(shù)中sizeof(arr)長度是40,數(shù)組中包含10個元素。
  • 而在函數(shù)erfen中,sizeof(arr)長度是4,數(shù)組中包含1個元素,就是首元素{ 1 }。

在這里插入圖片描述

由此,可知道,參數(shù)里傳遞數(shù)組時,實際傳遞的數(shù)組就是數(shù)組的地址,也是數(shù)組首元素的地址。數(shù)組名傳遞進來,只能是首地址,這個arr數(shù)組里只有首元素{1},長度為4。整個數(shù)組是傳遞不了的。因此,必須在主函數(shù)里求取數(shù)組的長度。

因為傳遞的參數(shù)是地址,所以erfen中也可以定義指針來接受數(shù)組:

//int erfen(int arr[])//接受數(shù)組,只能接受一個首元素
int erfen(int* arr)
{//數(shù)組傳遞進來,只能是首地址,這個arr數(shù)組里只有{1},長度為4
	int sz1 = sizeof(arr) / sizeof(arr[0]);,//4/4 = 1求出只有1個元素
	printf("erfen求數(shù)組大小,sz1:%d\n ", sz1);
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };	
	//數(shù)組長度為40
	int sz = sizeof(arr) / sizeof(arr[0]);//40/4 = 10 求出數(shù)組10個元素
	printf("main中求數(shù)組大小,sz:%d\n ", sz);
	erfen(arr);	
	return 0;
}

運行結果一樣

在這里插入圖片描述

4.3.4 數(shù)值自增增加1

寫一個函數(shù)用一次這個函數(shù),就會將 num 的值增加1

int add(int* p)
{
	(*p)++;//參數(shù)傳地址,可以操作實參的值
}
int main()
{
	int a = 10;
	add(&a);//傳地址
	printf("%d\n", a);
	add(&a);
	printf("%d\n", a);
	add(&a);
	printf("%d\n", a);
	add(&a);
	printf("%d\n", a);
	return 0;
}

5、函數(shù)的嵌套調用和鏈式訪問

函數(shù)和函數(shù)之間可以根據實際的需求進行組合的,也就是互相調用的。

5.1 嵌套調用

//套娃
void newline()
{
	printf("hehe\n");
}
void threeline()
{
	int i = 0;
	for (int i = 0; i < 3; i++)
	{
		newline();
	}
}
int main()
{
	threeline();
	newline;
	return 0;
}

5.2 鏈式訪問

把一個函數(shù)的返回值作為另外一個函數(shù)的參數(shù)。

int main()
{
	char arr[20] = "hello";
	int ret = strlen(strcat(arr, "bit"));
	printf("%d\n", ret);
	return 0;
}
int main()
{	
	printf("%d", printf("%d", printf("%d", 43)));//輸出4321,
	//前面是打印43 2是返回兩個字符(因為4 、3是兩個字符)  
	//1是返回1個字符(2是1個字符)

	return 0;
}

輸出結果見下圖:

在這里插入圖片描述

在這里插入圖片描述

總結

本文主要介紹了函數(shù)相關的知識,下一篇接著介紹函數(shù)的內容

到此這篇關于C語言函數(shù)超詳細講解上篇的文章就介紹到這了,更多相關C語言 函數(shù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Qt私有信號實現(xiàn)(private signal)

    Qt私有信號實現(xiàn)(private signal)

    在使用Qt信號槽機制的時候,有時候我們需要一個信號只能由類內發(fā)出,而不允許使用該類對象的用戶發(fā)出,此時就需要私有信號的支持,本文主要介紹了Qt私有信號實現(xiàn)(private signal),感興趣的可以了解一下
    2023-10-10
  • C++中const用于函數(shù)重載的示例代碼

    C++中const用于函數(shù)重載的示例代碼

    這篇文章主要介紹了C++中const用于函數(shù)重載的相關資料,需要的朋友可以參考下
    2017-09-09
  • 用C++實現(xiàn)DBSCAN聚類算法

    用C++實現(xiàn)DBSCAN聚類算法

    本篇文章是對使用C++實現(xiàn)DBSCAN聚類算法的方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言超全面講解函數(shù)的使用方法下

    C語言超全面講解函數(shù)的使用方法下

    函數(shù)是一組一起執(zhí)行一個任務的語句。每個?C?程序都至少有一個函數(shù),即主函數(shù)?main()?,所有簡單的程序都可以定義其他額外的函數(shù),由于篇幅過大,分為兩篇講解,下面開始下篇
    2022-04-04
  • Qt實現(xiàn)日志文件的滾動寫入

    Qt實現(xiàn)日志文件的滾動寫入

    這篇文章主要為大家介紹了如何使用Qt實現(xiàn)日志文件的滾動寫入功能,在日志文件達到10MB時創(chuàng)建新的日志文件,并且在總日志文件大小達到10GB時開始覆蓋最早的日志文件,需要的可以參考下
    2024-11-11
  • C/C++實現(xiàn)蛇形矩陣的示例代碼

    C/C++實現(xiàn)蛇形矩陣的示例代碼

    本文主要介紹了C/C++實現(xiàn)蛇形矩陣的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++ OpenCV實戰(zhàn)之手寫數(shù)字識別

    C++ OpenCV實戰(zhàn)之手寫數(shù)字識別

    這篇文章主要為大家詳細介紹了如何使用machine learning機器學習模塊進行手寫數(shù)字識別功能,文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-08-08
  • C語言基于EasyX庫實現(xiàn)有圖形界面時鐘

    C語言基于EasyX庫實現(xiàn)有圖形界面時鐘

    這篇文章主要為大家詳細介紹了C語言基于EasyX庫實現(xiàn)有圖形界面時鐘,獲得本地時間,輸出文字,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 深入C中常用的三種排序方法總結以及探討分析

    深入C中常用的三種排序方法總結以及探討分析

    本篇文章是對C中常用的三種排序方法總結以及探討分析的概述,需要的朋友參考下
    2013-05-05
  • c++ vector造成的內存泄漏問題

    c++ vector造成的內存泄漏問題

    這篇文章主要介紹了c++ vector造成的內存泄漏問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論

仁布县| 岱山县| 保靖县| 黔西县| 民县| 澎湖县| 施秉县| 正阳县| 交城县| 新乡县| 延安市| 卓资县| 台山市| 黄陵县| 乌苏市| 屯留县| 通海县| 赤水市| 察雅县| 大方县| 黄陵县| 蓬安县| 绥德县| 阿鲁科尔沁旗| 剑川县| 磐安县| 迁安市| 平谷区| 南京市| 永丰县| 花垣县| 盐山县| 怀宁县| 吐鲁番市| 边坝县| 禹州市| 嘉定区| 湟源县| 上犹县| 武功县| 海门市|