欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
c++之指針作為函數參數傳遞的問(wèn)題



其實(shí),對于C 或者C++ ,最難的一塊地方估計就是指針了。指針是強大的,但也是很多人載在這里的地方。

前段時(shí)間寫(xiě)了一篇文章《C ++之 數組與指針的異同 》對C C ++中的指針做了一個(gè)初步的講解。這次將講解一下指針作為函數參數傳遞的問(wèn)題。

很多人對于指針的使用是有所了解的,但還是經(jīng)常會(huì )載在指針的問(wèn)題上,是因為還不夠了解指針的本質(zhì),其實(shí)如果了解指針的本質(zhì),對指針的使用也就一目了然了。

作為C 的初學(xué)者,經(jīng)常會(huì )遇到指針作為函數參數傳遞的兩個(gè)經(jīng)典的問(wèn)題。這里,我將透過(guò)指針的本質(zhì)來(lái)來(lái)講解這兩個(gè)問(wèn)題,這樣以后無(wú)論你遇到什么樣的指針問(wèn)題,如果你以這樣的方法來(lái)分析指針也許就迎刃而解了!

首先,第一個(gè)問(wèn)題是這樣的:
寫(xiě)一個(gè)函數,交換兩個(gè)參數中的值。

初學(xué)者往往會(huì )這樣寫(xiě):

void exchange(int x, int y)
{
int p=x;
x = y;
y = p;
}

之后,你會(huì )查找資料了解到應該這樣寫(xiě):
void exchange(int
x, int y)
{
int
p=x;
x = y;
y = p;
}

第二個(gè)問(wèn)題是,寫(xiě)一個(gè)給某個(gè)指針?lè )峙鋬却娴暮瘮担?span lang="EN-US">
初學(xué)者往往是這樣寫(xiě):
void my_malloc(void* p, int size)
{
p = malloc(sizeof(int)*size);
}

然后又查在資料,知道應該這么寫(xiě):
void my_malloc(void** p, int size)
{
*p = malloc(sizeof(int)*size);
}

雖然,網(wǎng)上很多這樣的討論,也有很多人做過(guò)很多的解釋?zhuān)冀K都無(wú)法給出一個(gè)令人一目了然,并可以長(cháng)久記住的說(shuō)法,這篇文章就是想試圖解決這樣的問(wèn)題,給初學(xué)者一個(gè)原理性的了解!

首先,一定一定記住一點(diǎn), 指針和變量一樣,也是有地址的,只不過(guò)變量的值被解釋成一個(gè)值,而指針的值被解釋成一個(gè)地址。

下面,我們看一下代碼:
void main()
{
int x;
int *p;
}

我們看這個(gè)函數的內存結構:


這是一個(gè)函數的棧結構,我們可以看到,變量和指針都占用了4 個(gè)字節。而且,由于我們對它們沒(méi)有初始化,所以變量x 和指針p 里的內容都是隨機的,就是說(shuō)x 的值是不確定的,p 有可能指向某個(gè)內存地址,如果現在對p 操作也許會(huì )導致程序崩潰。

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

其實(shí),我們記住了,指針也是有地址的 這個(gè)概念,很多問(wèn)題就迎刃而解了。

下面,我來(lái)分析一下,指針作為函數參數傳遞的情況。
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
如果,我們的代碼是這樣的,你看會(huì )怎么樣:
int main(int argc, char* argv[])
{
int *a = new int(10);
func(a);
return 0;
}

第一個(gè)要說(shuō)的當然是:指針也是有地址的。
第二個(gè)要說(shuō)的是:當給一個(gè)函數的參數傳遞一個(gè)變量是,這個(gè)變量是復制過(guò)去的。

對于第二點(diǎn),我們在理解void exchange(int x, int y) 函數想交換這兩個(gè)變量的的值時(shí)就應該理解了。
例如:
int a;
int b;
exchange(a,b);
不能交換a b 的值,因為此時(shí)exchange(a,b) 中的a b 并不是原來(lái)的a b 變量,它們只不過(guò)是被復制過(guò)去了。

有了這兩個(gè)概念,就不難理解指針作為函數參數傳遞的問(wèn)題。

首先,我們來(lái)看下上面的代碼中的a 指針和p 指針的內存結構。

我們看到,當我們以a 作為func 函數的參數傳遞進(jìn)去的時(shí)候,函數復制了這個(gè)指針,但這兩個(gè)指針的內容是一樣的,也就是說(shuō)是指向同一個(gè)內存,即10 。


如果你還不了解的話(huà),我就通過(guò)一段代碼和測試再來(lái)說(shuō)明:

view plaincopy to clipboardprint?
#include <stdio.h> 
void func(int* p) 

    printf("*p = %d\n", *p); 
    printf("&p = %p\n", &p); 

int main(int argc, char *argv[]) 

    int *a = new int(10); 
    printf("*a = %d\n", *a); 
    printf("&a = %p\n", &a); 
    func(a); 
    return 0; 




編譯:g++ -g -Wall test1.cpp
運行:./a.out
輸出:
*a = 10
&a = 0xbfd4447c
*p = 10
&p = 0xbfd44460

我們看到輸出,a 指向的地址的值和p 指向的地址里的值是一樣的,都是10 。然而,對于指針a p 來(lái)說(shuō),它們自身的地址是不一樣的,所以我們看到,函數func 復制了指針a p ,它們的值一樣,但有不同的地址,是不同的指針。

我們再進(jìn)一步:
view plaincopy to clipboardprint?
#include <stdio.h> 
void func(int* p) 

    printf("*p = %d\n", *p); 
    printf("&p = %p\n", &p); 
    printf("&*p = %p\n", &*p); 

int main(int argc, char *argv[]) 

    int *a = new int(10); 
    printf("*a = %d\n", *a); 
    printf("&a = %p\n", &a); 
    printf("&*a = %p\n", &*a); 
    func(a); 
    return 0; 




編譯輸出:
*a = 10
&a = 0xbfe1c77c
&*a = 0x94b6008
*p = 10
&p = 0xbfe1c760
&*p = 0x94b6008

我們可以進(jìn)一步看到,a 指針所指向的值的地址和p 指針所指向的值的地址是一樣的,都是 0x94b6008 ,就如同上圖所示,為了加深印象,再看一下這個(gè)圖 ,然后再對比一下程序輸出 ,然后在體會(huì )一下我在上面提到的兩點(diǎn),一點(diǎn)是:指針是有地址的 。另一點(diǎn)是:函數的參數是復制過(guò)去的 。




說(shuō)到這里,我們再回到文章開(kāi)始時(shí)提到的兩個(gè)問(wèn)題,一個(gè)是交換問(wèn)題:

void exchange(int
x, int y)
{
int
p=x;
x = y;
y = p;
}

那么這樣為什么可以交換:
int a = 2;
int b = 3;
exchange(&a, &b);

上我們以a b 的地址傳遞給exchange 函數時(shí),函數復制了這兩個(gè)地址,并賦值給x y 這個(gè)兩個(gè)指針,這兩個(gè)指針是指向變量a b 的,它們的圖形如下:


那么,當我們反引用指針時(shí):
int
p=x;
x = y;
y = p;

我們操作的是a b 里面的變量的值,所以,我們交換a b 的值就成功了。

我們再來(lái)看下第二個(gè)問(wèn)題:
void my_malloc(void* p, int size)
{
p = malloc(sizeof(int)*size);
}
當這樣時(shí):
int *a;
my_malloc(a, 10);
為什么這個(gè)會(huì )失??!

下面,我來(lái)分析一下:
當我們調用my_malloc(a, 10); 函數,而函數還沒(méi)執行到p = malloc(size); 語(yǔ)句時(shí),情況是這樣的:


我們看到a p 的指針的值都是一樣的,都是指向某個(gè)不確定的地址。
這時(shí),我們執行這個(gè)語(yǔ)句:
p = malloc(sizeof(int)*size);
我們把這個(gè)語(yǔ)句分開(kāi)兩部分來(lái)看,一個(gè)是先執行malloc(sizeof(int)*size) ,然后在執行賦值語(yǔ)句,把malloc(sizeof(int)*size) 的返回值付給p 。
第一步:先執行malloc(sizeof(int)*size) ;(這里我們只考慮malloc 分配內存成功的情況)

第二步:把執行malloc(sizeof(int)*size) 的返回值付給了p ,如下圖:


由上圖,我們可以知道,這就是為什么,我們還是不能給a 分配地址的了。

下面我們來(lái)分析這個(gè):
void my_malloc(void** p, int size)
{
*p = malloc(sizeof(int)*size);
}

int *a;
my_malloc(&a
, 10);
這樣執行,為什么會(huì )成功!


我們看到,當執行函數
my_malloc(void** p, int size);
但還沒(méi)有執行
*p = malloc(sizeof(int)*size);
語(yǔ)句時(shí),它們的內存結構圖如下所示:


其實(shí)這里,我們可以把二維指針和一維指針當成和變量一樣,也是有地址的。只不過(guò)它的解釋不一樣而已。
變量:里面的值是一個(gè)數值。
一維指針:里面的值是個(gè)地址,而這個(gè)地址里的值是個(gè)數值。
二維指針:里面的值是個(gè)地址,而這個(gè)地址里的值也是個(gè)地址。

那么,我看著(zhù)圖來(lái)解釋p
p
里面是一個(gè)地址,這個(gè)地址是&a ,即是a 指針的地址值,而a 指針地址里面的值也是個(gè)地址,這個(gè)地址是指向一個(gè)不確定的地方,說(shuō)得坳口,慢慢對比圖來(lái)理解就會(huì )好了!

執行malloc(size) 后的圖如下:


然后在執行賦值語(yǔ)句:
*p = malloc(sizeof(int)*size);
后,如下圖所示:


然后,我們就給指針a 分配內存成功了。

 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C語(yǔ)言的那些小秘密之內存分配
C語(yǔ)言為指針動(dòng)態(tài)分配內存
內存分配不再神秘:深入剖析malloc函數實(shí)現原理與機制
指針強化
C語(yǔ)言難點(diǎn)分析整理
【轉載】C/C++的面試題
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久