C語言指針的傳遞
- C語言
- 關注:1.26W次
傳遞指針可以讓多個函數訪問指針所引用的對象,而不用把對象聲明為全局可訪問,要在某個函數中修改數據,需要用指針傳遞數據,當數據是需要修改的指針的時候,就要傳遞指針的指針,傳遞參數(包括指針)的時候,傳遞的是它們的值,也就是説,傳遞給函數的是參數值的一個副本,本文將討論C語言中指針傳遞給函數與從函數返回指針的內容。
用指針傳遞數據
用指針傳遞數據的一個主要原因是函數可以修改數據
下面的代碼實現一個常見的交換函數:
#include
void swap(int* a, int* b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int m, n;
m = 5;
n = 10;
printf("m=%d, n=%d",m, n);
swap(&m, &n);
printf("m=%d, n=%d",m, n);
return 0;
}
如果不通過指針傳遞參數,交換就不會發生,具體的原理參見任何一本C語言教材
傳遞指向常量的指針
傳遞指向常量的指針是C中常用的技術,效率很高,因為避免某種情況下複製大量內存,如果不希望數據被修改,就要傳遞指向常量的指針
我們不能修改通過指向常量的指針傳進來的值:
#include
void passconstant(const int* num1, int*num2)
{
*num2 = *num1;
}
int main()
{
const int a = 100;
int b = 5;
printf("a=%d, b=%d",a, b);
passconstant(&a, &b);
printf("a=%d, b=%d",a, b);
return 0;
}
下面的代碼會產生錯誤(第二個形參和實參的類型不匹配,試圖修改第一個參數所引用的常量):
#include
void passconstant(const int* num1, int* num2)
{
*num1 = 100;
*num2 = 200;
}
int main()
{
const int limit = 100;
passconstant(&limit, &limit);
return 0;}
C語言中堆和棧的區別
預備知識—程序的內存分配
一個由C編譯的程序佔用的內存分為以下幾個部分:
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
2、堆區(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表。
3、全局區(靜態區)(static),全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束後由系統釋放。
4、文字常量區 —常量字符串就是放在這裏的, 程序結束後由系統釋放
5、程序代碼區—存放函數體的二進制代碼。
下面就説説C語言程序內存分配中的堆和棧,內存分配一般情況下程序存放在Rom或Flash中,運行時需要拷到內存中執行,內存會分別存儲不同的信息,如下圖所示:
內存中的棧區處於相對較高的地址以地址的增長方向為上的話,棧地址是向下增長的,棧中分配局部變量空間,堆區是向上增長的用於分配程序員申請的內存空間。另外還有靜態區是分配靜態變量,全局變量空間的;只讀區是分配常量和程序代碼空間的;以及其他一些分區。
堆棧的區別,來看一個經典例子:
#include
#include
int a = 0; //全局初始化區
char *p1; //全局未初始化區
int main()
{
int b; //棧
char s[] = "abc"; //棧
char *p2; //棧
char *p3 = "123456"; //123456