- 相關(guān)推薦
C語言指針的傳遞
傳遞指針可以讓多個(gè)函數(shù)訪問指針?biāo)玫膶ο螅挥冒褜ο舐暶鳛槿挚稍L問,要在某個(gè)函數(shù)中修改數(shù)據(jù),需要用指針傳遞數(shù)據(jù),當(dāng)數(shù)據(jù)是需要修改的指針的時(shí)候,就要傳遞指針的指針,傳遞參數(shù)(包括指針)的時(shí)候,傳遞的是它們的值,也就是說,傳遞給函數(shù)的是參數(shù)值的一個(gè)副本,本文將討論C語言中指針傳遞給函數(shù)與從函數(shù)返回指針的內(nèi)容。
用指針傳遞數(shù)據(jù)
用指針傳遞數(shù)據(jù)的一個(gè)主要原因是函數(shù)可以修改數(shù)據(jù)
下面的代碼實(shí)現(xiàn)一個(gè)常見的交換函數(shù):
#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;
}
如果不通過指針傳遞參數(shù),交換就不會(huì)發(fā)生,具體的原理參見任何一本C語言教材
傳遞指向常量的指針
傳遞指向常量的指針是C中常用的技術(shù),效率很高,因?yàn)楸苊饽撤N情況下復(fù)制大量內(nèi)存,如果不希望數(shù)據(jù)被修改,就要傳遞指向常量的指針
我們不能修改通過指向常量的指針傳進(jìn)來的值:
#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;
}
下面的代碼會(huì)產(chǎn)生錯(cuò)誤(第二個(gè)形參和實(shí)參的類型不匹配,試圖修改第一個(gè)參數(shù)所引用的常量):
#include
void passconstant(const int* num1, int* num2)
{
*num1 = 100;
*num2 = 200;
}
int main()
{
const int limit = 100;
passconstant(&limit, &limit);
return 0;}
C語言中堆和棧的區(qū)別
預(yù)備知識(shí)—程序的內(nèi)存分配
一個(gè)由C編譯的程序占用的內(nèi)存分為以下幾個(gè)部分:
1、棧區(qū)(stack)— 由編譯器自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
2、堆區(qū)(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表。
3、全局區(qū)(靜態(tài)區(qū))(static),全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后由系統(tǒng)釋放。
4、文字常量區(qū) —常量字符串就是放在這里的, 程序結(jié)束后由系統(tǒng)釋放
5、程序代碼區(qū)—存放函數(shù)體的二進(jìn)制代碼。
下面就說說C語言程序內(nèi)存分配中的堆和棧,內(nèi)存分配一般情況下程序存放在Rom或Flash中,運(yùn)行時(shí)需要拷到內(nèi)存中執(zhí)行,內(nèi)存會(huì)分別存儲(chǔ)不同的信息,如下圖所示:
內(nèi)存中的棧區(qū)處于相對較高的地址以地址的增長方向?yàn)樯系脑挘瑮5刂肥窍蛳略鲩L的,棧中分配局部變量空間,堆區(qū)是向上增長的用于分配程序員申請的內(nèi)存空間。另外還有靜態(tài)區(qū)是分配靜態(tài)變量,全局變量空間的;只讀區(qū)是分配常量和程序代碼空間的;以及其他一些分區(qū)。
堆棧的區(qū)別,來看一個(gè)經(jīng)典例子:
#include
#include
int a = 0; //全局初始化區(qū)
char *p1; //全局未初始化區(qū)
int main()
{
int b; //棧
char s[] = "abc"; //棧
char *p2; //棧
char *p3 = "123456"; //123456