C語言指針的傳遞

傳遞指針可以讓多個函數訪問指針所引用的對象,而不用把對象聲明爲全局可訪問,要在某個函數中修改數據,需要用指針傳遞數據,當數據是需要修改的指針的時候,就要傳遞指針的指針,傳遞參數(包括指針)的時候,傳遞的是它們的值,也就是說,傳遞給函數的是參數值的一個副本,本文將討論C語言中指針傳遞給函數與從函數返回指針的內容。

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