您好,登錄后才能下訂單哦!
在C言語中,函數的參數不只可所以整數、小數、字符等詳細的數據,還可所以指向它們的指針。用指針變量作函數參數可以將函數內部的地址傳遞到函數外部,使得在函數外部可以操作函數內部的數據,而且這些數據不會跟著函數的完畢而被燒毀。
像數組、字符串、靜態分派的內存等多是一系列數據的聚集,沒有方法經過一個參數全體傳入函數外部,只能傳遞它們的指針,在函數外部經過指針來影響這些數據聚集。
有的時分,關于整數、小數、字符等根本類型數據的操作也必需要借助指針,一個典型的例子就是交流兩個變量的值。
有些初學者能夠會運用下面的辦法來交流兩個變量的值:
#include <stdio.h> void swap(int a, int b){ int temp; //暫時變量 temp = a; a = b; b = temp; } int main(){ int a = 66, b = 99; swap(a, b); printf("a = %d, b = %d\n", a, b); return 0; }
運轉后果:
a = 66, b = 99
從后果可以看出,a、b 的值并沒有發作改動,交流掉敗。這是由于 swap() 函數外部的 a、b 和 main() 函數外部的 a、b 是分歧的變量,占用分歧的內存,它們除了名字一樣,沒有其他任何干系,swap() 交流的是它外部 a、b 的值,不會影響它內部(main() 外部) a、b 的值。
改用指針變量作參數后就很輕易處理下面的成績:
#include <stdio.h> void swap(int *p1, int *p2){ int temp; //暫時變量 temp = *p1; *p1 = *p2; *p2 = temp; } int main(){ int a = 66, b = 99; swap(&a, &b); printf("a = %d, b = %d\n", a, b); return 0; }
運轉后果:
a = 99, b = 66
挪用 swap() 函數時,將變量 a、b 的地址辨別賦值給 p1、p2,如許 *p1、*p2 代表的就是變量 a、b 自身,交流 *p1、*p2 的值也就是交流 a、b 的值。函數運轉完畢后固然會將 p1、p2 燒毀,但它對內部 a、b 形成的影響是“耐久化”的,不會跟著函數的完畢而“恢恢復樣”。
需求留意的是暫時變量 temp,它的感化特殊主要,由于履行*p1 = *p2;語句后 a 的值會被 b 的值掩蓋,假如不先將 a 的值保管起來今后就找不到了。
數組是一系列數據的聚集,無法經過參數將它們一次性傳遞到函數外部,假如愿望在函數外部操作數組,必需傳遞數組指針。下面的例子界說了一個函數 max(),用來查找數組中值最大的元素:
#include <stdio.h> int max(int *intArr, int len){ int i, maxValue = intArr[0]; //假定第0個元素是最大值 for(i=1; i<len; i++){ if(maxValue < intArr[i]){ maxValue = intArr[i]; } } return maxValue; } int main(){ int nums[6], i, maxValue; int len = sizeof(nums)/sizeof(int); //讀取用戶輸出的數據并賦值給數組元素 for(i=0; i<len; i++){ scanf("%d", nums+i); } printf("Max value is %d!\n", max(nums, len)); return 0; }
運轉后果:
12 55 30 8 93 27↙
Max value is 93!
參數 intArr 僅僅是一個數組指針,在函數外部無法經過這個指針取得數組長度,必需將數組長度作為函數參數傳遞到函數外部。數組 nums 的每一個元素多是整數,scanf() 在讀取用戶輸出的整數時,請求給出存儲它的內存的地址,nums+i就是第 i 個數組元素的地址。
用數組做函數參數時,參數也可以以“真正”的數組方式給出。例如關于下面的 max() 函數,它的參數可以寫成下面的方式:
int max(int intArr[6], int len){ int i, maxValue = intArr[0]; //假定第0個元素是最大值 for(i=1; i<len; i++){ if(maxValue < intArr[i]){ maxValue = intArr[i]; } } return maxValue; }
int intArr[6]仿佛界說了一個具有 6 個元素的數組,挪用 max() 時可以將數組的一切元素“一股腦”傳遞出去。
讀者也可以省略數組長度,把形參簡寫為下面的方式:
int max(int intArr[], int len){ int i, maxValue = intArr[0]; //假定第0個元素是最大值 for(i=1; i<len; i++){ if(maxValue < intArr[i]){ maxValue = intArr[i]; } } return maxValue; }
int intArr[]固然界說了一個數組,但沒有指定命組長度,仿佛可以承受恣意長度的數組。
實踐上這兩種方式的數組界說多是假象,不論是int intArr[6]照樣int intArr[]都不會創立一個數組出來,編譯器也不會為它們分派內存,實踐的數組是不存在的,它們最終照樣會轉換為int *intArr如許的指針。這就意味著,兩種方式都不克不及將數組的一切元素“一股腦”傳遞出去,人人還得規規則矩運用數組指針。
int intArr[6]這種方式只能闡明函數希冀用戶傳遞的數組有 6 個元素,并不料味著數組只能有 6 個元素,真正傳遞的數組可以有少于或多于 6 個的元素。
需求強調的是,不論運用哪一種方法傳遞數組,都不克不及在函數外部求得數組長度,由于 intArr 僅僅是一個指針,而不是真正的數組,所以必需要額定添加一個參數來傳遞數組長度。
C言語為什么不許可直接傳遞數組的一切元素,而必需傳遞數組指針呢?
參數的傳遞實質上是一次賦值的進程,賦值就是對內存停止拷貝。所謂內存拷貝,是指將一塊內存上的數據復制到另一塊內存上。
關于像 int、float、char 等根本類型的數據,它們占用的內存常常只要幾個字節,對它們停止內存拷貝十分疾速。而數組是一系列數據的聚集,數據的數目沒無限制,能夠很少,也能夠不計其數,對它們停止內存拷貝有能夠是一個漫長的進程,會嚴重拖慢程序的效力,為了避免身手欠安的程序員寫出低效的代碼,C言語沒有從語法上支撐數據聚集的直接賦值。
除了C言語,C++、Java、Python 等其它言語也制止對大塊內存停止拷貝,在底層都運用相似指針的方法來完成。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。